为啥在 tableView 中创建一个重用标识符而不是分配/初始化一个单元格?

Posted

技术标签:

【中文标题】为啥在 tableView 中创建一个重用标识符而不是分配/初始化一个单元格?【英文标题】:Why create a reuseIdentifier instead of alloc/init a cell inside tableView?为什么在 tableView 中创建一个重用标识符而不是分配/初始化一个单元格? 【发布时间】:2014-04-22 16:59:09 【问题描述】:

我有一个存储为self.array 的NSStrings 数组。我是ios新手,我知道reuseIdentifier很可能有一个简单的优势让我无法理解,但是当以下内容也适用时,为什么还要经历所有这些麻烦和冗长的语法呢?

- (UITableViewCell *)tableView:(UITableView *)tableView 
    cellForRowAtIndexPath:(NSIndexPath *)indexPath 

    UITableViewCell *cell = [[UITableViewCell alloc] init];
    cell.textLabel.text = self.array[indexPath.row];

    return cell;

【问题讨论】:

您的代码可以正常工作。但是,如果您的表的行数多于几行,则效率会低得多。 你能解释一下为什么吗?我的印象是,reuseIdentifier 也需要为每个显示的单元格分配一个新单元格? 是的,但足以填满屏幕。一旦用户开始滚动,这些单元格就会被重用。在您的代码中,您将不断创建新单元格。 啊哈!我想有一个简单的目的!非常感谢,我会接受你的回答。 谢谢,但我没有发布答案。 【参考方案1】:

这是滚动的速度:重用单元格可以帮助您平滑滚动表格单元格。

拨打[[UITableViewCell alloc] init] 会无缘无故减慢速度。对于无所事事的细胞更难注意到,细胞变得越重,很快就越不光滑。预分配和重用单元格让您获得视觉上令人愉悦的滚动。

此外,丢弃的 CPU 周期会耗尽您的电池电量。用户可以以相当快的速度滚动表格,因此您在那里消耗的周期可以快速增加。

添加重用标识符消除了对[[UITableViewCell alloc] init] 的调用,超出了屏幕上可见的少数单元格。当一个单元格离开屏幕时,UITableView 将该单元格添加到可重复使用的单元格池中,从而消除了单元格本身实例的内存分配和释放。当您的tableView:cellForRowAtIndexPath: 请求新单元格时,UITableView 将返回一个已滚动屏幕的实例,因此您需要做的就是重新配置该实例,使其看起来像您需要显示的单元格.在许多情况下,重新配置现有单元比分配新单元要快得多。

这里是a link to a question with information on other things that you could do to improve the performance of your scrolls。

【讨论】:

这是正确的答案。没有它,你会得到表格滚动的抖动。 rmaddy 在问题 cmets 中解释说,一旦用户开始滚动,这些单元格就会被重用,不再分配。我认为这也是非常重要的一点,也没有包含在这个解释得很好的答案中。 啊,没关系,我实际上是在考虑以前的问题,我已经看到 op 在哪里创建了一个单元格数组并使用它来存储所有单元格。无论如何,问题...你是 ASCII Star Wars 流中的闪烁灯吗? @Fogmeister 不,我几乎随机选择了这个名字。 PS:ASCII星球大战动画太棒了!【参考方案2】:

您当前的方法每次都会创建一个新单元格,使用reuseIdentifier 允许表视图动态重用视图以节省内存分配。

您的代码可能会工作,但它不允许您的 tableView 尽可能高效。特别是当您的行数增加时。

【讨论】:

【参考方案3】:

正如之前所写,使用可重复使用的单元格更有效。您的应用程序将仅创建几个单元格,而不是与您的数组计数(或您想要显示的任何内容)一样多的单元格。 但请注意,如果您重复使用之前设置的单元格,则应重新定义其内容。 例如,如果您想在一个单元格中显示书名和副标题,并且您设置了一个包含内容的单元格,并且您重用了该单元格,但是此时该书没有字幕,该单元格将显示您之前的字幕之前已经设置好了,除非你清除它。

【讨论】:

以上是关于为啥在 tableView 中创建一个重用标识符而不是分配/初始化一个单元格?的主要内容,如果未能解决你的问题,请参考以下文章

JAVA中创建了多个对象,为什么只重复出现一个对象

使用重用标识符调用 super.tableView(tableView: UITableView, cellForRowAtIndexPath...

为啥我的 Tableview 重用了一些单元格?

我们如何在Android中重用已经在IOS中创建的Sqlite文件[重复]

为啥我的符号链接没有链接,而是在我试图链接的目录中创建一个文件

使用 swift 在 tableviewcell 内创建 tableview