免费开源的iOS开发学习平台

UITableView详解:7-单元格(UITableViewCell)性能优化

单元格性能优化的原理

UITableView中的单元格cell是在表视图显示到用户可视区域后创建的,如果用户向下滚动就会继续创建UITableViewCell对象,同时,假如用户向上滚动返回之前已经查看的内容时,同样也会重新创建新的UITableViewCell对象。即便是表视图UITableView的内容不是很多的情况下,如果用户反复的上下滚动,内存也会快速增加。另外,在诸如微博此类应用中,用户向下滑动可能加载的单元格数量是无限的。

出于对内存空间利用效率方面的考虑,在UITableView中,我们可以动态切换cell的内容来尽可能减少资源占用,将当前没有显示的cell重新显示在将要显示的Cell的位置然后更新其内容。在创建一个单元格时,我们需要根据单元格的样式类型为其指定一个可重用标识ID,当单元格移除屏幕后,该单元格对象会被暂时存放在缓存池中,即将被显示的单元格,会优先在缓存池中查找可重用标识ID一致的单元格,如果有相同的单元格,则直接复用,如果没有找到同样可重用标识的单元格才会重新创建。UITableView内部的缓存池机制是保证表视图高效响应用户交互的一个重要机制。

在UITableViewCell类中,定义了与缓存池机制密切相关的实例化方法。可重用标识可以有多个,如果在UITableView中有多类结构不同的Cell,可以通过这个标识进行缓存和重用

  • 根据可重用标识从缓存池中查找相同标识的单元格
- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;
  • 创建单元格,并指定其可重用标识
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(nullable NSString *)reuseIdentifier;

示例代码

下方的示例代码中,由于我们创建的单元格的样式是统一的,因此我们首先创建了一个静态变量cellID用于给每个单元格设置一个可重用标识号,而dequeueReusableCellWithIdentifier:方法负责从缓存池中首先查找是否有相同可重用标识的缓存单元格,如果没有找到,再调用initWithStyle:reuseIdentifier:方法创建单元格。

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    //初始化cell
    static NSString *cellID = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
    }
    //取值
    NSString *text = [NSString stringWithFormat:@"%d", arc4random_uniform(1000000)];
    //设值
    cell.textLabel.text = text;
    return cell;
}

除了通过代码创建单元格之外,通过xib创建的单元格也可以指定其可重用标识符。

示例代码

https://github.com/99ios/8.2.7