【问题标题】:NSFetchedResultsController + UICollectionView - handling NSFetchedResultsChangeUpdateNSFetchedResultsController + UICollectionView - 处理 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;

这工作得更快,结果看起来不错。

问题:

  1. 这是一个正确的解决方案吗?我有没有弄坏什么东西?
  2. 有更好的解决方案吗?

【问题讨论】:

标签: objective-c core-data uicollectionview nsfetchedresultscontroller


【解决方案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 的解决方案是可行的。
猜你喜欢
  • 2012-07-11
  • 2016-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-01
  • 1970-01-01
相关资源
最近更新 更多