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的主要内容,如果未能解决你的问题,请参考以下文章

在 Core Data 应用程序中调用 performFetch 后,是不是需要手动更新表视图?