使用dequeueReusableCellWithIdentifier不会显得更快(或更低的内存)?

时间:2014-02-28 18:08:09

标签: ios objective-c cocoa-touch uitableview

当我想创建一个包含自定义单元格的表格时,我将编写标准代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"CustomCell";
    CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil)
    {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
        cell = [topLevelObjects objectAtIndex:0];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }
    else
    {
        NSLog(@"reuse!");
    }

    cell.property1 = ....
    cell.property2 = ....
    return cell;
} 

这大致是我将如何创建自定义单元格:

  • 创建一个CustomCell.h(继承UITableViewCell)和CustomCell.m以及一个CustomCell.xib
  • 在CustomCell.xib中
  • ,将顶级 UIView 的'class'属性更改为'CustomClass'

我已经这样做了一段时间,但今天我终于决定做一个测试,看看该表是否真正重用了单元格。

不。该表不会重复使用任何单元格!上面的代码片段中的NSLog(@“reuse!”)永远不会被触发。

我决定使用这两种方法进行性能比较,其中包含100万个单元格的tableview:

方法#1 使用上述方法。请注意,UIView是我的CustomCell.xib中的顶级视图,并且没有在xib上配置重用标识符

  • 单元格未重复使用(NSLog重复使用!未打印)
  • 峰值内存大约3.4MB,峰值CPU 60%
  • 滚动顺畅

方法#2 在xib的顶层使用UITableViewCell,我将所有控件放在此UITableViewCell的内容视图中。在XIB中,我将此单元的重用标识符配置为“CustomCell”。

  • 单元格重用(NSLog重复使用多次打印)
  • 峰值内存约6.1MB,峰值CPU约88%
  • 滚动顺畅

两个问题:

  1. 为什么我没有看到方法#2上的CPU和内存使用率低得多,方法#1错误而方法#2是否正确,因为方法#1根本没有重用任何单元格?或者从另一个角度来看,为什么方法#1仍然滚动得那么好,即使它一次又一次地愚蠢地加载笔尖?

  2. 为自定义单元格创建自定义xib时,顶级对象是否为UIViewnor UITableViewCell会有什么不同吗? (看起来没什么区别?)

2 个答案:

答案 0 :(得分:4)

似乎在您的XIB文件中未正确设置reuseIdentifier

您也可以通过添加

以编程方式设置它
[yourTable registerNib:[UINib nibWithNibName:@"CustomCell" bundle:nil] forCellReuseIdentifier:@"CustomCell"];

在使用表格视图之前的某个地方。例如viewDidLoad

更新

问题1.如果您没有设置单元格重用标识符单元格,则生命周期如下:

1.它已创建。

2.显示出来。

3.它被移出可见区域。

4.不再需要它,所以它被删除了。

如果使用重用标识符单元格TYPICAL生命周期是:

1.它从可重复使用的队列中弹出..

2.显示出来。

3.它被移出可见区域。

4.它被推送到可重复使用的队列。

因此性能差异是由于执行速度更快:创建/释放操作或弹出/推送。两种变体的内存使用量应该大致相同。

答案 1 :(得分:1)

你需要实施

-(NSString *)reuseIdentifier {

return @"CustomCell";

} 

在您的单元格小组CustomCell中,因为reuseIdentifier只读属性,您无法从外部设置