UITableView在iOS開發中會經常使用,對於行數很多的UITableView,可以通過UITableViewCell的重用,來保證執行效率。源碼下載點擊這裡。
我們通過代碼來探索UITableViewCell重用的實現,下面是一段使用UITableView的代碼,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *CellIdentifier = @"myCell"; //NSString *CellIdentifier = [NSString stringWithFormat:@"myCell_%d",indexPath.row]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewStyleGrouped reuseIdentifier:@"myCell"]; UITextField *tf; tf = [[UITextField alloc] initWithFrame:CGRectMake(100, 10, 150, 40) ]; tf.delegate = self; tf.borderStyle = UITextBorderStyleRoundedRect; [cell addSubview:tf]; [tf release]; } // Configure the cell... cell.textLabel.text = [NSString stringWithFormat:@"%d",indexPath.row]; return cell;}
運行結果是這樣
我們在textfield裡輸入label的序號,然而我們上下拖動後,結果是textfield的值並沒有得到儲存,其隨著cell的重用而變化。
我們回到dequeueReusableCellWithIdentifier的定義
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier; // Used by the delegate to acquire an already allocated cell, in lieu of allocating a new one.
使用委託來擷取一個已經分配的cell,代替分配新的一個;在這個例子中,將當前螢幕下建立的Cell都先加入到對象池,這是對象池的內Cell的個數大致是8,當我們滑動TableView時,將使用dequeueReusableCellWithIdentifier方法返回對象,該方法通過
reuseIdentifier(“myCell”)在對象池中,尋找之前已經放入的cell對象。
然後從對象池中,取出之前放入的,然後執行
// Configure the cell... cell.textLabel.text = [NSString stringWithFormat:@"%d",indexPath.row];
所以我們需要為textfield裡的text內容設定model層,然後配置textfield的內容,像我們對textLabel的設定一樣
還有了不完美的解決方案,既然它重用出問題,就不讓它重用,代碼如下
NSString *CellIdentifier = [NSString stringWithFormat:@"myCell_%d",indexPath.row];
對於每一行,設定不同的reuseIdentifier。