UITableView為了做到顯示與數據的分離, 單獨使用了一個叫UITableViewCell的視圖用來顯示每一行的數據, 而tableView得重用機制就是每次只創建屏幕顯示區域內的cell,通過重用標識符identifier來標記cell, 當cell要從屏幕外移入屏幕內時, 系統會從重用池內找到相同標識符的cell, 然后拿來顯示, 這樣本是為了減少過大的內存使用, 但在很多時候, 我們會自定義cell,這時就會出現一些我們不願意看到的現象, 下面就介紹一些解決這些問題的方法
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath]; // 這句代碼就是造成cell的重用的代碼
在cell中我布局了左邊一個imageView, 右邊一個Label, 總共顯示20行
1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 2 MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath]; 3 cell.myLabel.text = [NSString stringWithFormat:@"我的Label%ld", indexPath.row]; 4 if (indexPath.row == 5) { 5 cell.imageVIew.backgroundColor = [UIColor greenColor]; 6 } 7 return cell; 8 }
在cellForRow這個方法中可以看到當row等於5時, 我將imageView的背景顏色變為綠色, 按理說20行中應該只有第五行的imageView為綠色, 但是實際效果呢, 看下圖

可以明顯看到不止第五行, 11, 17行也變成了綠色, 這就是cell的重用造成的一個我們不願意看到的問題, 當第5行移出屏幕時, 被系統放入了重用池內, 當要顯示第11行時,系統優先從重用池內找到了5行的cell, 造成其上的imageView也被復制過來了, 下面簡單介紹一些解決cell重用的方法
- 給每個cell做一個tag標記,對cell將要展示的差異內容進行判斷
1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 2 MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath]; 3 cell.myLabel.text = [NSString stringWithFormat:@"我的Label%ld", indexPath.row]; 4 cell.tag = indexPath.row; 5 if (cell.tag == 5) { 6 cell.imageVIew.backgroundColor = [UIColor greenColor]; 7 } 8 if (cell.tag != 5) { 9 cell.imageVIew.backgroundColor = [UIColor whiteColor]; 10 } 11 return cell; 12 }
2.將cell的identifier設為唯一的, 保證了唯一性
1 NSString *identifier = [NSString stringWithFormat:@"%ld%ldcell", indexPath.section, indexPath.row]; 2 MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
3.不使用系統的重用機制, 此方法在數據量較大時會造成過大的內存使用
1 MyTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
4.刪除將要重用的cell上的所有子視圖, 得到一個沒有內容的cell
1 [(UIView*)[cell.contentView.subviews lastObject] removeFromSuperview];
關於解決cell的重用的方法還有很多, 就不在此一一介紹了, 希望能給你一點感悟
