坏的UITableViewCell性能自动版式 [英] UITableViewCell bad performance with AutoLayout
问题描述
我有点卡住了这一个...任何帮助是非常AP preciated。我已经花了很多时间调试此。
I'm somewhat stuck with this one… any help is very appreciated. I've already spent lots of time debugging this.
我已经有了的UITableView
与 NSFetchedResultsController
提供的数据源。在一个单独的视图控制器我使用插入新记录到CoreData [NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:]
,表示被管理对象上下文并关闭该控制器。很标准的东西。
I've got UITableView
with data source provided by NSFetchedResultsController
. In a separate view controller I insert new records to the CoreData using [NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:]
, save the managed object context and dismiss that controller. Very standard stuff.
在管理对象方面的变化,然后由收 NSFetchedResultsController
:
The changes in managed object context are then received by 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;
}
}
这是问题出现的地方 - 它的时间太长(约3-4秒在iPhone 4)做到这一点。而且好像时间都花在计算布局单元格。
And this is where the problem appears — it takes too long(about 3-4 seconds on an iPhone 4) to do that. And it seems like the time is spent calculating layout for the cells.
我从小区(包括自定义子类)剥离一切,只用的UILabel
,但没有改变离开它。然后,我已经改变了细胞基本(或自定义以外的任何东西)的风格,问题就消失了 - 新的细胞在瞬间补充
I've stripped everything from the cell(including custom subclass) and left it with just UILabel
, but nothing changed. Then I've changed the style of the cell to Basic(or anything except Custom) and the problem disappeared — new cells are added instantaneously.
我已经翻了一番检查和 NSFetchedResultsControllerDelegate
回调称为一次。如果我不理会他们,做 [UITableView的reloadSections:withRowAnimation:]
,没有什么变化 - 它仍然是非常缓慢的。
I've doubled checked and NSFetchedResultsControllerDelegate
callbacks are called only once. If I ignore them and do [UITableView reloadSections:withRowAnimation:]
, nothing changes — it is still very slow.
在我看来,像自动布局是默认单元格样式,这使得它们非常快禁用。但是,如果是这样的话 - 为什么做一切能够快速加载,当我推的UITableViewController
It seems to me like Auto Layout is disabled for the default cell styles, which makes them very fast. But if that is the case — why does everything loads quickly when I push the UITableViewController
?
下面对于此问题的呼叫跟踪:
Here's the call trace for that problem:
所以,问题是 - 什么是怎么回事?为什么细胞被渲染得很慢?
So the question is — what is going on here? Why are cells being rendered so slowly?
更新1
我已经建立了一个非常简单的演示程序,说明我有这个问题。这里的源 - <一个href=\"https://github.com/antstorm/UITableViewCellPerformanceProblem\">https://github.com/antstorm/UITableViewCellPerformanceProblem
I've built a very simple demo app that illustrates the problem I'm having. here's the source — https://github.com/antstorm/UITableViewCellPerformanceProblem
尝试增加至少细胞满屏感受到性能问题。
Try adding at least a screenful of cells to feel the performance problems.
另外请注意,直接添加行(现在插入!按钮),没有造成任何进展缓慢。
Also note that adding a row directly ("Insert now!" button) is not causing any slowness.
推荐答案
好吧,我终于绕不牺牲动漫这个问题了。我的解决方法是实施的UITableViewCell
的与自动版式残疾人单独护理文件的界面。这需要一点点更长的加载时间,你需要的位置子视图自己。
Ok, I finally got around this problem without sacrificing animation. My solution is to implement UITableViewCell
's interface in a separate Nib file with AutoLayout disabled. It takes a little bit longer to load and you need to positions subviews yourself.
这里的code,使之成为可能:
Here's the code to make it possible:
- (void)viewDidLoad {
[super viewDidLoad];
...
UINib *rowCellNib = [UINib nibWithNibName:@"RowCell" bundle:nil];
[self.tableView registerNib:rowCellNib forCellReuseIdentifier:@"ROW_CELL"];
}
当然,你需要用你的手机的视图RowCell.nib文件。
Of course you'll need a RowCell.nib file with your cell's view.
虽然没有解决原来的问题(这显然似乎是一个错误给我),我使用的这一个。
While there's no solution to the original problem(which clearly seems a bug to me), I'm using this one.
这篇关于坏的UITableViewCell性能自动版式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!