【问题标题】:Implement UITableViewDataSourcePrefetching with an NSFetchedResultsController data source使用 NSFetchedResultsController 数据源实现 UITableViewDataSourcePrefetching
【发布时间】:2017-06-27 22:32:13
【问题描述】:

我有一个从NSFetchedResultsController 获取数据的 UITableView。为此,我基本上从https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/nsfetchedresultscontroller.html复制了Apple的示例实现。

现在,在 WWDC16 上,Apple 宣布了 UITableViewDataSourcePrefetching 协议,该协议提供回调,让您可以预取数据,以便在需要由 tableview 显示时已经加载。我正在寻找一个关于如何将其与NSFetchedResultsController 集成的示例,因为我无法确定我是否正确执行此操作。

  • 我是否应该简单地创建一个字典作为内存缓存来保存预取数据并在cellForRowAtIndexPath 中使用,而不是直接查询fetchedResultsController.object(at: indexPath)
  • 据我了解,CoreData 已经自动缓存了获取的数据,所以也许我只需要在预取回调中调用fetchedResultsController.object(at: indexPath),以确保数据被缓存?
  • 或者我不应该在使用 fetched results 控制器时预取数据,因为我会绕过 Apple 提供的神奇集成?
  • 或者完全是别的什么?

*edit*:我在 WWDC16 的 Core Data 演讲中找到了一张幻灯片,据说可以解释这一点,但我完全理解。

  • 异步获取请求?我认为他们不适用于NSFetchedResultsController。我想这就是为什么它直接在managedObjectContext 上执行?
  • 异步获取请求是根据在NSFetchedResultsController 上调用.performFetch() 的结果创建的。在我打电话之前什么都没有出现。但是由于调用它后所有结果都在那里,我不明白为什么我需要再次预取它们。

【问题讨论】:

    标签: ios swift core-data uikit


    【解决方案1】:

    如果您的模型有故障,它将提高性能。您的模型是否有故障取决于 iOS 优化,以及您如何创建架构和关系。

    为了安全起见,您可以添加预取代码。我有 Swift 4 的代码。

    func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
        let fetchRequest: NSFetchRequest<MyModel> = MyModel.fetchRequest()
        fetchRequest.returnsObjectsAsFaults = false
        let items = indexPaths.map { fetchedResultsController.object(at: $0) }
        fetchRequest.predicate = NSPredicate(format: "SELF IN %@", items)
        let asyncFetchRequest = NSAsynchronousFetchRequest(fetchRequest: fetchRequest)
        do {
            try fetchedResultsController.managedObjectContext.execute(asyncFetchRequest)
        } catch { }
    }
    

    它的作用是不言自明的。它在托管对象上下文上运行异步获取请求,从而解决故障(如果有)。

    【讨论】:

      【解决方案2】:

      简而言之,您正在创建一个自定义谓词来“加热” MOC 中预测的特定对象。我认为,这个想法是表格视图告诉您更多有针对性的滚动目标信息(基于速度等),它认为表格视图将结束。这允许您执行异步请求以在 MOC 中预取这些对象,以便在您实际请求其属性时,它们已准备就绪。

      这就是为什么您在异步请求上也有一个 nil 完成。您没有直接使用结果,因为您实际上可能还没有显示任何这些索引路径。这也意味着当您获得预取对象时,无需对结果进行额外跟踪(如在Dictionary 等中)。

      真正的问题是,如果您使用具有批处理、预取属性等功能的 FRC,这真的是为了让您回避它吗?我不太确定。我没有注意到一个相当高度调整的 FRC+UITableView 与没有预取大约 1000 个结果的表之间的巨大差异。也可以通过仅触摸 FRC 将看到的那些对象(因为您共享相同的 MOC)然后将运行它的属性/关系预取等。我没有看到太多关于此机制的文档,但是如果 Apple 建议这样做,尤其是使用 FRC,我认为它会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-30
        • 2021-08-31
        • 1970-01-01
        相关资源
        最近更新 更多