微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

调用 performFetch

如何解决调用 performFetch

问题

在执行 NSBatchBatchInsertRequest调用 fetchedResultsController.performFetch() 后,frc 的委托方法 controller(_:didChangeContentWith:)调用,其中 NSDiffableDataSourceSnapshot<Section,NSManagedobjectID> 意外地包含 all 数据核心数据(即使我刚刚插入了数据)。

代码

NSFetchedResultsController 的创建方法如下:

    let fetchedResultsController = NSFetchedResultsController<MyManagedobject>(
        fetchRequest: fetchRequest,managedobjectContext: persistentContainer.viewContext,sectionNameKeyPath: nil,cacheName: nil
    )

NSFetchRequest

    let fetchRequest = MyManagedobject.fetchRequest()
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "value",ascending: true)]
    fetchRequest.fetchBatchSize = 10

快照应用在下面的此 NSFetchedResultsControllerDelegate 方法中。

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>,didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) {
    dataSource.apply(snapshot as NSDiffableDataSourceSnapshot<Section,NSManagedobjectID>,animatingDifferences: false)
}

详情

  • 示例应用每 5 秒接收 10,000 个 Item 实例,并在带有 NSBatchInsertRequest 的新背景上下文上运行 performAndWait 以将 Item 转换并存储为 {{ 1}} 个实例。
  • MyManagedobject 然后在 performFetch() 上被调用
  • 调用 main 可确保在 controller(_:didChangeContentWith:) 中提供新快照,数据源可以apply(_:animatingDifferences:completion:) 更新 UI。
  • 这些项目填充一个 performFetch(),该 UICollectionView 连接到一个 UICollectionViewDiffableDataSource<Section,NSManagedobjectID>
    • 当要求数据源为特定的 NSManagedobjectID 制作单元格时,使用 MyManagedobject 为该 NSManagedobjectID 制作正确的 fetchedResultsController.managedobjectContext.object(with:)
    • 然后将 MyManagedobject 转换为 Item,最终用于配置单元。

尝试解决方

对我来说最明显的解决方案是仅实现此委托方法,但该方法似乎并未被调用

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>,didChangeContentWith diff: CollectionDifference<NSManagedobjectID>) {
    print(diff)
}

我不希望在获取数据时 UI 卡顿和挂起。我认为发生这种情况的原因是我的快照很大。我猜他们为什么这么大是因为我的 fetch 请求获取了所有数据(但我只想将 new 数据添加到快照中)。为了解决这个问题,我尝试将 fetchLimit 设置为一个像 2 这样的小数字,但这只会导致只提取 2 个项目。我想我可以通过更新 fetchOffset解决这个问题,但是当我滚动时这种方法可能会变得混乱。调整 fetchBatchSize 没有什么区别。内存也没有泄漏。 FWIW,我正在后台队列中应用快照,但这似乎也没有改善 UI 卡顿。

我想在获取项目时将它们存储到 Core Data,然后仅在滚动到屏幕外单元格时从持久存储中获取。这似乎正在发生,因为我可以看到数据源仅在应用快照时请求可见范围附近的索引路径的单元格(即使集合视图的垂直滚动条随着时间的推移而缩小)。 但是快照的大小(=到目前为止收到的项目总数)在不断增加

我可以获取当前快照并仅附加新快照中缺少的项目,但这仍然需要我通过无限大小的快照。如何避免这样做并加载大量数据而不会出现 UI 卡顿现象?我只是将数据插入到 Core Data 中,那么为什么我会在快照中获取所有数据?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。