当CoreData更新时,UITableView endUpdates需要很长时间

时间:2016-04-27 21:06:39

标签: ios objective-c uitableview core-data

我有一个核心数据应用,可在UITableView中显示大量实例。

我们在主线程中运行mainQueueContext,在后台线程中运行privateQueueContext

我们在UITableView中加载数据没有问题,但是当我们从API加载刷新版本时,我们将其保存到privateQueueContext并将其合并到mainQueueContext

[self.mainQueueContext mergeChangesFromContextDidSaveNotification:notification];

触发对

的调用需要几秒钟
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller

触发调用:

[self.tableView endUpdates];

然后应用程序挂起,CPU进入100%,内存开始无限期上升,直到内存不足为止。 (见下图)

CPU during the processing

Memory consumption during endUpdates

少于1000个元素,这个问题不会发生。我想知道你们有没有看到这样的事情。

修改

这里有来自乐器的一些数据 Instruments data showing endUpdates

3 个答案:

答案 0 :(得分:1)

您可以做的一项改进是使用fetchBatchSize

来自Apple Doc“

  

执行提取时,将评估整个请求并执行   记录的所有匹配对象的标识,但不超过   batchSize对象的数据将从a的持久性存储中获取   时间。从执行请求返回的数组将是一个代理   根据需要透明地对批次进行故障的对象。 (在数据库中   术语,这是一个内存中的游标。)

您还可以使用fetchLimit和fetchOffset来实现分页。

干杯, 的Alessandro

答案 1 :(得分:1)

我也遇到过这个问题。我最终收集了所有更新到controller: didChangeObject:记录索引路径,NSFetchedResultsChangeType和对象本身的数组。在controllerDidChangeContent:我查看它的计数是否大于X,如果它只是重​​新加载整个表(它效率更高),如果它不是那么通常应用所有更改,就像它发生在{{1} } 方法。插入/删除/移动如此多的单元格是没有意义的,因为用户无论如何都不会看到大部分这些更改。

我希望这种方法可以帮到你!

答案 2 :(得分:1)

我遇到了类似的问题。在我的情况下,解决方案是将tableView的显式rowHeight设置为UITableViewAutomaticDimension

tableView.rowHeight = UITableViewAutomaticDimension

我代之以委托tableView(_:heightForRowAt:) 虽然rowHeight的文档似乎反过来说:

  

使用tableView(:heightForRowAt :)而不是rowHeight会对性能产生影响。每次显示表视图时,它会在委托上为每个行调用tableView(:heightForRowAt :),这会导致表视图具有大量行(大约1000或大约1000)的显着性能问题更多)。