UITableView dequeueReusableCellWithIdentifier理论
当苹果公司为第一款iPhone开发UITableView
,它们在性能上遇到了问题。 然后一位聪明的工程师发现,原因是物体的分配带来了一个代价,所以他想出了一种重用细胞的方法。
“对象分配具有性能成本,特别是如果分配必须在短时间内重复发生,例如用户滚动表视图时,如果重复使用单元而不是分配新单元,则可大大提高表视图的性能。
来源:iOS参考图书馆
重用您使用的单元格:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
现在,我想知道的是,这里究竟发生了什么? 如果有一个具有该标识符的单元格并返回该单元格,它会在TableView中查看吗? 那么啊是啊,但如果它发送一个引用而不是分配,我有一个表视图与我们说4个单元格具有相同的标识符都是可见的。 它怎样才能把自己分成四个实例而不分配?
我想知道这一点,因为我正在build立一个日历types的组件,所有的单元格具有相同的结构只有文本内的变化。 所以如果我能以某种方式重新使用我的电池,而不是分配,我想我可能会获得更好的性能。
我自己的理论是它分配了四个单元格(因为它也有)。 当一个单元格从屏幕上消失时,它将被放在TableView的重用队列中。 当需要一个新的单元时,它会查询具有相同标识符的单元是否可用,它会在该单元上调用prepareForReuse
方法,并将其从队列中移除。
dequeueReusableCellWithIdentifier:
只返回一个cell
如果它已被标记为可重用。 这就是为什么在几乎每个cellForRowAtIndexPath:
方法中,你会看到类似的东西
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (nil == cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } // Do something to cell return cell;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (nil == cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } // Do something to cell return cell;
实际上,将分配足够的行来填充tableview
的可见部分(加上一两个更多)。 当cells scroll
从屏幕上cells scroll
出来时,它们将从table
中移出并标记为可以reuse
。 随着“可用单元格”队列的增长,要求dequeued cell
行将开始获取要使用的cell
,此时不必再分配。
deqeueueReusableCellsWithIdentifier:
的代码如下所示:
(从我自己的一个项目中,我在页面滚动视图中执行与视图/页面类似的操作)
- (UIView*) dequeueReusablePage { UIView* page = [reusablePages_ anyObject]; if (page != nil) { [[page retain] autorelease]; [reusablePages_ removeObject: page]; } return page; }
所以它保持一个简单的NSMutableSet
与可重用的对象。
当单元格滚动屏幕,不再可见,他们被放在这个集合。
所以你从一个空集合开始,只有当你真正有更多的数据显示,然后在屏幕上可见时,集合才会增长。
使用的单元格从屏幕顶部滚动,放入设置中,然后用于显示在屏幕底部的单元格。
dequeueReusableCellWithIdentifier
的用途是使用较less的内存。 如果我们在tableView中使用100个单元格,则需要每次创build100个单元格。它会降低应用程序的function并可能导致崩溃。 对于那个dequeueReusableCellWithIdentifier
初始化我们创build的特定数量的单元格,这些单元格将再次用于进一步处理。
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *TableIdentifier = @"YourCellIdentifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TableIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TableIdentifier]; } ExternalClassTableViewCell *myCell = [[ExternalClassTableViewCell alloc]init]; myCell.MyCellText.text = [tableData objectAtIndex:indexPath.row]; myCell.MyCellImage.backgroundColor = [UIColor blueColor]; return cell; }