UITableView的重用機制

iphone重用機制是蘋果爲了實現大量數據顯示而採用的一種節省內存的機制,比如在UITableView和ScrollView 等地方。爲什麼要“可重用”???對於我們的項目來說,內存控制是必不可少的,如果一個tableview有幾百個cell,這個內存消耗是很大的,而且有些cell裏面都有image之類的很佔內存的資源存在的話,那這樣很容易出現memory warning甚至crash掉,這不是我們想要看到的。對此,tableview實現了它自己的管理方法dequeueReusableCellWithIdentifier(ps:我們在某些項目中scrollview來顯示很多張image,在scrollview滑動中也要這樣處理,來避免內存的過度消耗,只不過tableview它已經實現了這個方法,而不用我們自己去寫)。

但是在實際使用過程中,會有以下問題:

1、(蘋果文檔中不鼓勵我們在UITableViewCell中添加subView,最好採用自定義Cell,將需要的SubView添加到Cell當中。)使用addSubView在每項上添加視圖的時候會有重疊的現象。例如,UITableView中的Cell ,如果在cell上添加子視圖,則在使用蘋果的重用機制的時候,會重現子試圖重疊的現象。或出現開頭提到的兩個問題。如果在數據量不是很多的時候,可以手動屏蔽掉UITableView的重用機制。

這裏不得不提一下UITableView的重用機制:

UITableView的重用機制的實現關鍵在於下面這個的函數:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

首先,我們要清楚這一點,這個函數是做什麼的,它的文檔說明如下:
returns a reusable table-view cell object located by its identifier。它返回的是一個受identifier管理定位的可重用的tableViewCell,這裏重點就在於“可重用”這3個字上。

我們來看它的實現方法,舉個例子來說,在系統剛啓動時,tableview可以顯示多少個cell,在這裏我們假定爲10個,在剛開始的時候tableview會生成10個tableviewcell,並且對應有自己的tag值,假定爲0-9。(ps:蘋果官方的視頻中也提到了,儘量避免頻繁的add/remove view或者控件之類等。自定義啊自定義,相對於Android 空間的自定義,)所以採用下面的方法來實現:在tableview向上滾動的時候,tag爲0的cell將不再顯示;然後我們把tag爲0的cell移動到tag爲9的cell下面,重新設置相關的屬性,然後將tag爲1的cell移動到tag爲0的cell下面……依此類推。這也就是所謂的“可重用”。

但是此時被移動的tag爲0的cell的一些屬性還是保持不變的(包括之前添加的subView),因此就會出現一些無厘頭的bug(看了這麼多,到這裏是不是鬆了口氣? )。

         接下來我們就要使用多種的方法來幹掉這個重用機制:          

         (1):  

                      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

                      if (cell != nil) {

                                [cell release];  //怎麼樣?? 換了位置的Cell囂張不了了吧....

                             }


        (2): //和(1)的方法本質一樣,略顯囉嗦。

UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {

cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:CellIdentifier]autorelease];

}

       NSArray*subviews = [[NSArrayalloc]initWithArray:cell.contentView.subviews];

for (UIView *subview in subviews) {

[subviewremoveFromSuperview];

}

[subviews release];


           //customer 


                      return cell;

  }

(3)://丫的,組別都不一樣,看你怎麼重用。

           NSString *CellIdentifier = [NSString stringWithFormat:@"cell%d",indexPath.row];
    
           UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
          if (cell == nil) 

                {
                               ........
                 }
         else{
                        return cell;
               }            

    

雖然幹掉了重構機制,但我還是時不時地會想念它,特別是在數據多的時候,使用重用機制會好對你的程序的內存使用和優化都有很重要的作用。 但是這樣的話,如果想再cell上添加東西的話,重疊現象會很嚴重。好吧,魚和熊掌捆綁銷售啦啦!!使用xib給cell添加視圖來添加視圖吧......

具體步驟:

(1)新建一個基於UITableViewCell的類A和一個空白的xib。

(2)在A類中聲明要添加的視圖,例如IBOutlet UILabel *nameLabel,*timeLabel; ,注意:一要是使用  IBOutlet。

(3)將xib中的view刪除,拖一個 UITableViewCell,然後將這個UITableViewCell的類改爲基於A。再把相應的視圖添在UITableViewCell上,並且與A類內定義的變量進行連接。這樣準備工作就完成了。

(4)使用方法:

                 A* cell = (A*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];


                 if (cell == nil) {


                         NSArray* nib = [[NSBundle mainBundle] loadNibNamed:@"VideoCell" owner:self options:nil];


                         cell = [nib objectAtIndex:0];


                 }

           然後只需在下面改變cell相應視圖的屬性就可以了。

補充:在使用地圖MKMapView一會使用到重用機制,如果想要在MKPinAnnotationView添加視圖的話,最好放棄那個重用機制,要不然效果會亂七八糟的(估計還有更好的處理方法)~~

    什麼,你不喜歡用Xib?好吧,這個老外寫的UITableView的代碼,估計會合你的口味,實現方式如下:

    1、cell中的釋放

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        cell = [[[UITableViewCell alloc] init....] autorelease];

        UITextField *field = ...;//初始化

        [cell addSubView:field];//添加

        [field release];//釋放   

       }

     2、通過遍歷修改UILabel屬性

  UITextField*field = nil;

   for(UIView *v in cell.contentView.subviews)

   {

         if([v isMemberOfClass:[UILabel class]])

             field = (UITextField *)v;

   }


             ......//接下來修改field的屬性


發佈了17 篇原創文章 · 獲贊 0 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章