iOS中的UITableView的重用机制与加载优化详解

2020-01-18 20:09:36刘景俊

UITableView可以说是UIKit中最重要的一个组件,用来展示数据列表,还可以灵活使用进行页面的布局。UITableView的使用遵循MVC模式,数据模型(NSObject)、视图(UIView)和控制器(UITableViewController)分离。UITableView继承自UIScrollView,可上下滑动,可以作为跟视图也可以作为子视图组件。

reuseIdentifier顾名思义是一个复用标识符,是一个自定义的独一无二的字符串,用来唯一地标记某种重复样式的可复用UITableViewCell,系统是通过reuseIdentifier来确定已经创建了的指定样式的cell来进行复用,iOS中表格的cell通过复用来提高加载效率,因为多数情况下表格中的cell样式都是重复的,只是数据模型不同而已,因此系统可以在保证创建足够数量的cell铺满屏幕的前提下,通过保存并重复使用已经创建的cell来提高加载效率和优化内存,避免不停地创建和销毁cell元素。

UITableViewCell的复用原理其实很简单,可以通过下面一个简单的例子来理解:

首先在开发中我们在UITableViewController类中写cell复用代码的最基本模板会像下面这样:


/**
 * 可复用cell制作
 */
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  // 定义cell重用的静态标志符
  static NSString *cell_id = @"cell_id_demo";
  // 优先使用可复用的cell
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_id];
  // 如果要复用的cell还没有创建,则创建一个供之后复用
  if (cell == nil) {
    // 新创建cell并使用cell_id复用符标记
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cell_id];
  }
  // 配置cell数据
  cell.textLabel.text = [NSString stringWithFormat:@"Cell%i", countNumber];
  // 其他cell设置...
  return cell;
}

代码这样写的原因是通过调用当前tableView的dequeueReusableCellWithIdentifier方法看指定的reuseIdentifier是否有可以重复使用的了,如果有则会返回可复用的cell,cell就绪之后便可以开始更新cell的数据;如果还不可复用,则返回nil,然后会进入后面的if语句,此时创建新的cell并对其设置cell样式标记reuseIdentifier。注意上面的if语句并不是只要执行一次创建一次新的cell就完成任务,然后之后全部重复利用新创建的那一个cell,这是对cell复用机制的误解。

事实是要创建足够数量的可覆盖整个tableView的可复用cell之后才会开始复用之前的(UITableView中有一个visiableCells数组保存当前屏幕可见的cell,还有一个reusableTableCells数组用来保存那些可复用的cell),这个我们用下面的测试来验证。

如何简洁清楚的展示UITableViewCell的复用机制呢?这里的方法是创建最基本的文本cell,并创建一个cell创建计数器,每次新创建cell计数器加1并显示在cell上,如果是复用的cell则会显示是复用的哪一个cell,测试代码如下: