NSFetchedResultsController + UICollectionView - 处理 NSFetchedResultsChangeUpdate
Posted
技术标签:
【中文标题】NSFetchedResultsController + UICollectionView - 处理 NSFetchedResultsChangeUpdate【英文标题】:NSFetchedResultsController + UICollectionView - handling NSFetchedResultsChangeUpdate 【发布时间】:2014-07-13 09:34:42 【问题描述】:我正在尝试在集合视图中显示来自 CoreData 的数据。我尝试了AshFurrow's code 和其他变体,以将NSFetchedResultsController
观察到的数据的变化反映到集合视图中。它似乎有效。
问题是我在后台对数据进行了大量处理,包括添加新项目、添加部分、删除部分甚至合并部分。这会导致 UI、滚动显着延迟。我注意到大部分时间都花在更新更改的集合视图项上:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
[self.collectionView performBatchUpdates:^
....
case NSFetchedResultsChangeUpdate:
[self.collectionView reloadItemsAtIndexPaths:@[indexPath]];
break;
....
];
此代码似乎重新加载了甚至无缘无故不可见的项目。所以我把它改成:
case NSFetchedResultsChangeUpdate:
if ([[self.collectionView indexPathsForVisibleItems] containsObject:indexPath])
[self.collectionView reloadItemsAtIndexPaths:@[indexPath]];
break;
这工作得更快,结果看起来不错。
问题:
-
这是一个正确的解决方案吗?我有没有弄坏什么东西?
有更好的解决方案吗?
【问题讨论】:
对我来说看起来不错。您可以在 github.com/AshFurrow/… 上提出问题并提出您的解决方案。 【参考方案1】:您可以通过在controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
中实现重新加载来限制对相关索引路径的更新
而不是controllerDidChangeContent:
【讨论】:
我实际上缓存了来自controller:didChangeObject
的所有相关索引路径,以便在controllerDidChangeContent
中进行批量更新。 controller:didChangeObject
为所有更改的获取对象调用,即使是不可见的。
那么您的解决方案虽然非标准,但很好。
@Mundi:问题在于 UICollectionView 没有 begin/endUpdates 方法(如在 UITableView 中)。对应的 UICollectionView 方法是 performBatchUpdates:completion:,但这与 NSFetchedResultsController 配合得不好。 Ash Furrow 的 AFMasterViewController.m 是解决该问题的方法,比较 ashfurrow.com/blog/…。据我所知,没有“标准”解决方案。
@MartinR 感谢您的链接。 (总是很高兴阅读您的输入。)这个问题的一个很好的抽象解决方案。在这种情况下,OP 的解决方案是可行的。以上是关于NSFetchedResultsController + UICollectionView - 处理 NSFetchedResultsChangeUpdate的主要内容,如果未能解决你的问题,请参考以下文章