【问题标题】: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,我认为它会有所帮助。