UITableView dequeueReusableCellWithIdentifier Theory

Mar*_*ark 33 iphone uitableview reuseidentifier

当苹果UITableView为第一款iPhone 开发时,他们在滚动浏览时会遇到性能问题.然后,一位聪明的工程师发现,造成这种情况的原因是物品的分配需要付出代价,因此他想出了一种重用细胞的方法.

"对象分配具有性能成本,特别是如果分配必须在短时间内重复发生 - 例如,当用户滚动表视图时.如果重用单元而不是分配新单元,则可以大大提高表视图性能."

来源:iOS参考图书馆

要重用您使用的单元格:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Run Code Online (Sandbox Code Playgroud)

现在,我想知道的是,这里究竟发生了什么?如果有一个具有该标识符的单元格并且只返回那个标识符,它是否在TableView中查找?好吧,但是,如果它发送一个引用而不是分配,我有一个表视图,让我们说4个具有相同标识符的单元格都可见.如何在不分配的情况下将自身增加到四个实例中?

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

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

Jer*_*nes 43

dequeueReusableCellWithIdentifier:cell如果已标记为可以重复使用,则仅返回a .这就是为什么在几乎每种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.随着"可用单元格"队列的增长,请求a的dequeued cell行将开始获取cell使用,此时您将不再需要分配.

  • "一两个"部分是不正确的.它准确地分配了*所需的东西.尝试一下,你会看到. (3认同)
  • 就我解释的方式而言,我可能有点仓促."需要什么"取决于具体情况.当您开始滚动UITableView时,会有更多因素发挥作用.一个示例:如果您非常快速地滚动长表视图,则可能会导致表在没有可用于出列的情况下请求单元格. (2认同)

Ste*_*ntz 13

代码deqeueueReusableCellsWithIdentifier:看起来像这样:

(取自我自己的项目之一,我在页面滚动视图中执行与视图/页面类似的操作)

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

因此它使NSMutableSet可重用对象保持简单.

当单元格从屏幕滚动并且不再可见时,它们将被放入此集合中.

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

使用过的单元格从屏幕顶部滚动,放入集合中,然后拍摄出现在屏幕底部的单元格.