2010-08-23 82 views
32

当苹果为第一款iPhone开发UITableView时,它们在滚动时遇到了性能问题。然后一位聪明的工程师发现,其原因是物体的分配带有价格,所以他想出了一种重用单元的方法。UITableView dequeueReusableCellWithIdentifier理论

“对象分配有性能上的成本,尤其是如果分配有在短期内,比如说,当 用户滚动表视图。如果你重用的小区,而不是分配 新的,反复发生的大大提升桌面表现。“

来源:iOS的参考库

要重新使用单元格使用:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

现在,我想知道是,到底发生了什么吗?如果有一个具有该标识符的单元格并返回该单元格,它是否会查看TableView?好吧,是啊,但如果它发送一个引用而不是分配,我有一个表视图,让我们说4个单元格具有相同的标识符都是可见的。它怎样才能将自身扩展为四个实例而不分配?

我想知道这一点,因为我正在构建日历类型组件,并且所有单元格都具有相同的结构,只有更改中的文本。所以如果我能以某种方式重用我的单元而不是分配,我想我可能会获得更好的性能。

我自己的理论是它分配了四个单元格(因为它也有)。当一个单元从屏幕上消失时,它将被放入TableView重用队列中。当需要一个新的单元时,它会查询具有相同标识符的单元是否可用,它会在该单元上调用prepareForReuse方法,并将其自身从队列中移除。

+0

简答:是的。它有一个单独的重用队列/集合,与表中已有的不同。 – 2010-08-23 23:18:15

回答

43

dequeueReusableCellWithIdentifier:只返回cell如果它已被标记为可以重新使用。这就是为什么几乎所有的cellForRowAtIndexPath:方法,你会看到类似

 


UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

if (nil == cell) { 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
            reuseIdentifier:CellIdentifier]; 
} 

// Do something to cell 

return cell; 
 

实际上,足够的行会被分配到填充的tableview(加一或两个以上)的可见部分。由于屏幕上有cells scroll,因此将它们从table中删除,并标记为reuse。随着“可用单元格”队列的增长,请求dequeued cell的线路将开始获取要使用的cell,此时您不必再分配。

+3

'一个或两个以上'部分不正确。它恰好分配了*所需要的。试试这个,你会看到。 – 2010-08-23 23:18:51

+0

确实如St3fan所说,如果你NSLog的方法,它会要求一个细胞,你会看到它只会要求所需的细胞。 – Mark 2010-08-24 08:23:42

+2

我的解释是,我可能有点匆忙。 “需要什么”取决于环境。当你开始滚动UITableView时,更多因素起作用。举一个例子:如果你非常快速地滚动一个长表视图,当没有任何可用于出列时,可能会导致表请求一个单元格。 – 2010-08-24 08:53:54

13

deqeueueReusableCellsWithIdentifier:代码将是这个样子:

- (UIView*) dequeueReusablePage 
{ 
    UIView* page = [reusablePages_ anyObject]; 
    if (page != nil) { 
     [[page retain] autorelease]; 
     [reusablePages_ removeObject: page]; 
    } 
    return page; 
} 

(从我自己的项目,我做的分页滚动视图的意见/页类似的东西之一获得)所以这用可重复使用的对象保持简单的NSMutableSet

当单元格从屏幕上滚动出来并且不再可见时,它们被放入这个集合中。

所以你从一个空集合开始,只有当你有更多的数据要显示然后在屏幕上可见时,集合才会增长。

已使用的单元格从屏幕顶部滚动,放入设置中,然后拍摄出现在屏幕底部的单元格。

2

dequeueReusableCellWithIdentifier的用途是使用较少的内存。如果我们在tableView中使用100个单元格,则需要每次创建100个单元格。它会降低应用程序的功能并可能导致崩溃。 对于该dequeueReusableCellWithIdentifier初始化我们创建的特定数量的单元格,单元格将再次使用以进一步处理。

-(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; 
} 
相关问题