NSFetchedResultsController 性能问题
Posted
技术标签:
【中文标题】NSFetchedResultsController 性能问题【英文标题】:NSFetchedResultsController performance issues 【发布时间】:2013-03-27 13:11:37 【问题描述】:我有一个带有 5 个标签的标签栏控制器。每个选项卡都有一个表格视图控制器。其中两个是 NSFetchedResultsControllers。
每当用户点击表格视图中的某个项目时,该项目首先会被保存到历史记录中,然后会继续显示。其中一个 NSFetchedResultsController 显示查看项目的历史记录,按日期排序。
当这些 NSFetchedResultsController 都没有被延迟实例化时,性能很好:
13:41:50.485 Saving to history…
13:41:50.487 CoreData: sql: BEGIN EXCLUSIVE
13:41:50.490 CoreData: sql: UPDATE ZSLBOOK SET ZDATEADDEDTOHISTORY = ?, Z_OPT = ? WHERE Z_PK = ? AND Z_OPT = ?
13:41:50.495 CoreData: sql: COMMIT
13:41:50.511 Saved
但是在负责显示历史的 NSFetchedResultsControllers 实例化后,速度会急剧下降,需要一到两秒(加上渲染下一个视图),所以应用程序似乎挂起。
13:42:08.750 Saving to history…
13:42:08.752 Will change
13:42:08.753 Object changed
13:42:09.579 Did change
13:42:09.594 CoreData: sql: BEGIN EXCLUSIVE
13:42:09.596 CoreData: sql: UPDATE ZSLBOOK SET ZCOVERIMAGE = ?, ZDATEADDEDTOHISTORY = ?, Z_OPT = ? WHERE Z_PK = ? AND Z_OPT = ?
13:42:09.619 CoreData: sql: COMMIT
13:42:09.637 Saved
只是为了让你知道发生了什么,这是我更新历史的代码:
- (void)addToHistory
NSLog(@"Saving to history…");
self.book.dateAddedToHistory = [NSDate date];
NSError *error;
[self.managedObjectContext save:&error];
NSLog(@"Saved");
在这些方法中调用日志消息:
controllerWillChangeContent ("Will change")
controller:didChangeObject ("Object changed")
controllerDidChangeContent ("Did change")
NSFetchedResultsController 是标准实现的。即使我只有几行(5-10),性能也很慢。 Core Data 很好(从日志中可以看出它非常快),我将批量大小设置为 20,有索引等。所以问题出在 NSFetchedResultsController 的某个地方。
其中一种可能性是将 TVC 的获取结果控制器委托设置为 nil。但是管理更新非常困难,选择行并滚动到最后一个位置(因为您需要重新加载数据)。
您有什么想法可能导致问题吗?我不相信这种表现是正常的,因为有无数行的表格会在瞬间加载和显示。
【问题讨论】:
你有没有在仪器下运行它来查看时间花在了哪里?通常它在 processChanges 通知方法上。 是的,没错,大部分时间都花在了 postNotificationName:object:userInfo 中。似乎它正在重新绘制背景中的表格并为其设置动画。这个子流程花费的时间最多:-[UIView(Hierarchy) layoutBelowIfNeeded]。 【参考方案1】:通过使用免费的 Sensible TableView 框架,您可以完全避免使用 NSFetchedResultsController。该框架将自动获取您的数据并将其显示在表视图上,包括生成所有详细视图 UI 和关系视图。根据我的经验,这比过去使用 NSFetchedResultsController 更有效。
【讨论】:
以上是关于NSFetchedResultsController 性能问题的主要内容,如果未能解决你的问题,请参考以下文章