1. 程式人生 > >用xib自定義UITableViewCell的注意事項——重用問題

用xib自定義UITableViewCell的注意事項——重用問題

問題的提出:

有時候我們經常需要自定義tableView的cell,當cell裡面的佈局較為複雜時往往捨棄純程式碼的方式而改用xib的方式進行自定義。當我們用純程式碼的方式佈局cell時,往往會在cell的initWithStyle: reuseIdentifier: 方法裡面用純程式碼進行佈局,然後在外部VC的cellForRowAtIndexPath方法裡面我們會這麼寫,假定自定義的cell為Cell,繼承自UITableViewCell:

static NSString *CellIdentifier = @"Cell";
    Cell *cell = (Cell *)[tableView dequeueReusableCellWithIdentifier
:CellIdentifier];
if (!cell) { cell = [[[Cell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } cell.titleLabel.text = [self.dataList objectAtIndex:indexPath.row]; return cell;

上述這麼寫完全沒有問題,因為教科書跟各種教程都是這麼寫的,上述程式碼對cell進行了重用。但如果我們現在想用xib來佈局呢?看到過不少程式碼是這麼寫的:

static NSString *CellIdentifier = @"Cell";
    Cell *cell = (Cell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        
        cell = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([Cell class])
                                             owner:self
                                           options:
nil] objectAtIndex:0];
//cell = [[[Cell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } cell.titleLabel.text = [self.dataList objectAtIndex:indexPath.row];return cell;

唯一區別的地方在於紅色的位置:cell的初始化不再通過initWithStyle函式,因為我們現在用xib佈局,所有的控制元件資訊都在xib裡面,因此我們根據Cell所對應的xib名稱來載入xib以建立cell。但是你注意到沒,第二種方法的紅色部分並沒有包含任何重用資訊,也就是說,每次拖動tableview,都會一直建立不同的cell,當要顯示的cell很多時記憶體問題就顯露出來了。

為了解決這個問題,我們換用另一種更好的方式。

直接放優化後的程式碼,UINib類可以先不看,不影響程式碼的理解:

static NSString *CellIdentifier = @"Cell";
    BOOL nibsRegistered = NO;
    if (!nibsRegistered) {
        UINib *nib = [UINib nibWithNibName:NSStringFromClass([Cell class]) bundle:nil];
        [tableView registerNib:nib forCellReuseIdentifier:CellIdentifier];
        nibsRegistered = YES;
    }
    Cell *cell = (Cell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    cell.titleLabel.text = [self.dataList objectAtIndex:indexPath.row];
    return cell;

我們可以看到,紅色部分很好地滿足了我們的需求:既從nib載入,又能對cell進行重用。下面對程式碼進行解釋:

1.UINib是一個IOS4.0才出現的類,與MAC上的NSNib類作用相似, 就是加速頻繁使用的NIB檔案的載入。在第一次從硬碟載入NIB時,它在記憶體中快取NIB檔案物件。之後載入NIB檔案時就會從記憶體拷貝而避免了較慢的硬碟訪問。Apple宣稱可以在 載入NIB檔案時提供 2倍的速度提升 。 使用UINib的最明顯的地方就是在需要在每次建立新Cell時從NIB檔案中載入Cell的UITableViewControllers中。UINib的優勢就是在不用大量修改程式碼的情況獲得性能改進。其實簡單地說,就是利用快取機制避免了頻繁從硬碟中載入XIB檔案,這在大資料量的時候顯得尤為有用。

2.除了上述程式碼,還需要在xib檔案中做如下設定:在Cell.xib的Inspector視窗中將Identifier進行設定,這裡的Identifier要與cellForRowAtIndexPath中一致。

以上就是從xib載入自定義UITableViewCell的注意事項以及解決方案,很多人採用了第二種方法,看起來雖然沒問題但是一旦記憶體吃緊的時候問題就暴露出來了!