为啥在 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 中创建一个重用标识符而不是分配/初始化一个单元格?的主要内容,如果未能解决你的问题,请参考以下文章
使用重用标识符调用 super.tableView(tableView: UITableView, cellForRowAtIndexPath...
我们如何在Android中重用已经在IOS中创建的Sqlite文件[重复]