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; } 
Interesting Posts