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的重用的方法还有很多, 就不在此一一介绍了, 希望能给你一点感悟
|