通过预加载单元格提高 UITableView 性能

Posted

技术标签:

【中文标题】通过预加载单元格提高 UITableView 性能【英文标题】:Improving UITableView performance by pre-loading cells 【发布时间】:2014-06-18 17:41:35 【问题描述】:

我有一个UIPageViewController,其中每个页面的视图都包含一个UITableView。我想在控制器之间进行分页时提高性能。

我会在方便的时候在当前页面的任一侧预加载一些控制器,并询问他们的视图以确保提前呈现所有内容。但真正的瓶颈实际上是 tableview 的单元格,它们没有被预加载:

MyViewController *vc = [[MyViewController alloc] initWithNibName:nil bundle:nil];

[vc view];
NSLog(@"view: %@", vc.view); // view exists

[vc tableview];
NSLog(@"tableview: %@", vc.tableview); // tableview exists

UITableViewCell *cell = [vc.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
NSLog(@"cell: %@", cell); // cell is null??

如日志所示,直到 tableview 实际出现在屏幕上,单元格本身才会被加载。

如何让屏幕外的UITableView 提前出列其可见单元格?

【问题讨论】:

细胞长什么样?你剖析过吗?听起来这可能是图像解压缩的问题,在这种情况下,您可以进行一些明确的优化。您能否提供单元格的屏幕截图? 没有图像,当然我可以对单元格进行一些优化。但我最感兴趣的是为什么即使明确要求表格视图也不加载单元格。 【参考方案1】:

它返回 nil 是因为当您调用 [vc.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 时,您调用的是表视图对象上的方法,而不是您的数据源(即您的视图控制器)。

这与表格视图在您创建单元格的数据源(即视图控制器)上调用- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 不同。

您调用的方法要求表格视图返回它已经为您传入的索引路径的单元格。由于在此阶段表格视图没有向您的数据源询问任何单元格(因为它不可见),它没有单元格可以给你,因此返回 nil。

如果您想预加载单元格,您可以在后台线程上创建第一批,方法是为初始行创建索引路径,并要求数据源返回单元格。将它们存储在一个数组中,然后让您的- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 实现在表格视图请求它们时从数组中返回前几个索引路径的初始化单元格。

【讨论】:

非常有趣,谢谢。我想知道有多少性能特征与单元格创建与将单元格添加到视图相关联。我怀疑这样的预加载会改善前者,但不会改善后者。希望这就足够了——我会分析并返回。 我也在尝试一些巧妙的方法来确定为一个屏幕的内容预加载多少个单元格;不出所料,在 tableview 出现之前,visibleCells 为 0。 效果很好,谢谢。也有很大的改进空间——下一步可能是在 tableviews 之间共享重用队列。 如果您预先知道单元格的高度,那么您可以根据视图控制器的视图高度进行计算吗?另一个想法,您是否使用具有自动布局的可变高度单元?您发现时间分析仪有什么有趣的地方吗? 所以为了确认,我们必须提前手动调用 our 自己的(即 vc 的而不是 tableview 的)- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 并将单元格存储在一个数组中,这样下次 the tableview 调用我们的 vc 函数时,我们只需要返回这些单元格(当然假设数据没有变化)?

以上是关于通过预加载单元格提高 UITableView 性能的主要内容,如果未能解决你的问题,请参考以下文章

在 UITableView 内的 UIImageView 中从 Web 加载图像

UITableview 不通过 willdisplaycell 选择单元格

(Swift)如何通过重新加载 UITableView 根据 UITextfield 输入(动画)显示/隐藏单元格?

将uitableview重新加载到底部单元格

自动选择单元格 UITableView

UITableView - 当它们离开屏幕时不要卸载单元格