Nic*_*ing 2 objective-c nsfetchedresultscontroller uicollectionview uicollectionviewlayout
我有一个300个单元格的集合视图,由NSFetchedResultsController驱动.每隔一段时间,所有对象都会更新,所以我收到委托消息告诉我,并让集合视图处理更新,就像我查看tableview一样.不幸的是,每次发生这种情况时它会锁定主线程几秒钟......我不知道为什么.这是我的代码:
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.cascadeViewController.collectionView performBatchUpdates:^{
NSLog(@"performingBatchUpdates");
for (NSDictionary *change in self.changes) {
[change enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, id obj, BOOL *stop) {
NSFetchedResultsChangeType type = [key unsignedIntegerValue];
if (type == NSFetchedResultsChangeInsert) {
[self.cascadeViewController.collectionView insertItemsAtIndexPaths:@[obj]];
} else if (type == NSFetchedResultsChangeDelete) {
[self.cascadeViewController.collectionView deleteItemsAtIndexPaths:@[obj]];
} else if (type == NSFetchedResultsChangeUpdate) {
[self.cascadeViewController.collectionView reloadItemsAtIndexPaths:@[obj]];
} else if (type == NSFetchedResultsChangeMove) {
[self.cascadeViewController.collectionView moveItemAtIndexPath:obj[0] toIndexPath:obj[1]];
}
}];
}
NSLog(@"performingBatchUpdates end");
} completion:^(BOOL finished) {
NSLog(@"completion");
// TODO: implement
// [self configureMessageAndFooterView];
}];
NSLog(@"end of method");
[self.changes removeAllObjects];
}
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?一次更新的所有300个对象不会在我的应用程序的实际执行中不断发生,但足以让我担心它.我正在使用股票UICollectionViewFlowLayout - 我需要做一些更自定义的事情吗?
小智 5
performBatchUpdates:completion:在大约100个元素的集合视图中锁定主线程几秒钟也有同样的问题.
在花费太多时间在这个问题上我找到了一个解决方案:确保单元格的大小(-collectionView:layout:sizeForItemAtIndexPath:通过itemSize布局属性返回或定义)没有小数值.我通过应用floor计算出的细胞高度解决了我的性能问题.
话虽如此,我不知道为什么会这样.通过观察我们的异形运行的堆栈跟踪,大量的时间都花在了-[UIViewCollectionViewUpdate _computeGaps],这反过来调用-[NSArray sortedArrayUsingSelector:]数百甚至数千倍(以及CFSortIndexes,__CFSimpleMergeSort...).通过仅使用整数值作为单元格的高度,sortedArrayUsingSelector调用次数少于10次,整个过程在几分之一秒内完成.
| 归档时间: |
|
| 查看次数: |
1472 次 |
| 最近记录: |