- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有点受困于此……非常感谢任何帮助。我已经花了很多时间对此进行调试。
我有 UITableView
,其数据源由 NSFetchedResultsController
提供。在单独的 View Controller 中,我使用 [NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:]
将新记录插入到 CoreData,保存托管对象上下文并关闭该 Controller 。非常标准的东西。
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
,但没有任何改变。然后我将单元格的样式更改为 Basic(或除 Custom 之外的任何样式),问题消失了 — 新单元格立即添加。
我仔细检查了 NSFetchedResultsControllerDelegate
回调只调用了一次。如果我忽略它们并执行 [UITableView reloadSections:withRowAnimation:]
,没有任何变化 — 它仍然很慢。
在我看来,默认单元格样式禁用了自动布局,这使得它们非常快。但如果是这样的话——为什么当我按下 UITableViewController
时一切都加载得很快?
这是该问题的调用跟踪:
所以问题是——这里发生了什么?为什么单元格渲染如此缓慢?
更新 1
我构建了一个非常简单的演示应用程序来说明我遇到的问题。这是来源 — https://github.com/antstorm/UITableViewCellPerformanceProblem
尝试添加至少一屏的单元格以感受性能问题。
另请注意,直接添加一行(“立即插入!”按钮)不会导致任何缓慢。
最佳答案
Auto Layout 确实会影响性能。但是,在大多数情况下,它并不是很明显。在一些具有复杂布局的边缘情况下,摆脱它会产生有意义的差异,但这并不是真正的问题。
我没有很好的解释为什么应用程序会以现在的方式运行,但至少我有一个解决方案:如果表格 View 不在屏幕上,则不要更新表格 View 。这导致了这种奇怪的行为。
为此,您可以例如在获取的结果 Controller 的委托(delegate)方法中检查 self.tableview.window != nil
。然后你只需要添加一个 [self.tableview reloadData]
到 viewWillAppear
以便表格 View 在出现在屏幕上之前更新它的数据。
希望对您有所帮助。如果有人对这种奇怪的行为有很好的解释,请告诉我:)
关于iphone - AutoLayout 的 UITableViewCell 性能不佳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16949248/
我是一名优秀的程序员,十分优秀!