我有点坚持这个......非常感谢任何帮助。我已经花了很多时间调试这个。
我得到UITableView
了由NSFetchedResultsController
. 在一个单独的视图控制器中,我使用 向 CoreData 插入新记录[NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:]
,保存托管对象上下文并关闭该控制器。很标准的东西。
然后通过以下方式接收托管对象上下文中的更改NSFetchedResultsController
:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
switch (type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeUpdate:
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
}
}
这就是问题出现的地方——它需要很长时间(在 iPhone 4 上大约 3-4 秒)才能做到这一点。似乎时间都花在了计算单元格的布局上。
我已经从单元格中剥离了所有内容(包括自定义子类),并将其保留为UILabel
,但没有任何改变。然后我将单元格的样式更改为基本(或除自定义之外的任何内容)并且问题消失了 - 立即添加了新单元格。
我已经检查了两倍,并且NSFetchedResultsControllerDelegate
只调用了一次回调。如果我忽略它们并做[UITableView reloadSections:withRowAnimation:]
,没有任何改变——它仍然很慢。
在我看来,默认单元格样式禁用了自动布局,这使得它们非常快。但如果是这样的话——为什么当我按下 时一切都加载得很快UITableViewController
?
这是该问题的调用跟踪:
所以问题是——这里发生了什么?为什么细胞渲染如此缓慢?
更新 1
我构建了一个非常简单的演示应用程序来说明我遇到的问题。这是来源- https://github.com/antstorm/UITableViewCellPerformanceProblem
尝试添加至少一屏单元格来感受性能问题。
另请注意,直接添加一行(“立即插入!”按钮)不会导致任何缓慢。