Che*_*eng 5 core-data ios swift
newBackgroundContext苹果在其官方地震示例中向我们展示了如何使用后台线程(通过使用)执行繁重的写入操作- https://github.com/yccheok/earthquakes-WWDC20
但是,对于大量的读操作呢?(数百万行用于压力测试目的)
当我们第一次启动应用程序并且应用程序正在从 CoreData 读取大量数据时,我们还希望我们的应用程序 UI 具有响应能力。
以下是使用的代码片段NSFetchedResultController。
let controller = NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: persistentContainer.viewContext,
sectionNameKeyPath: nil, cacheName: nil)
controller.delegate = fetchedResultsControllerDelegate
// Perform the fetch.
do {
// This statement tooks some time to complete if you have a lot of rows.
try controller.performFetch()
} catch {
fatalError("Unresolved error \(error)")
}
Run Code Online (Sandbox Code Playgroud)
我们尝试controller.performFetch()使用后台线程来执行。尽管如此,但不知道为什么,用户界面仍然没有响应能力。我的猜测是,在NSFetchedResultsController占用UI主线程之后,要执行一些耗时的I/O读操作。
let controller = NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: persistentContainer.viewContext,
sectionNameKeyPath: nil, cacheName: nil)
controller.delegate = fetchedResultsControllerDelegate
DispatchQueue.global(qos: .background).async {
// Perform the fetch.
do {
// This statement tooks some time to complete if you have a lot of rows.
try controller.performFetch()
} catch {
fatalError("Unresolved error \(error)")
}
}
Run Code Online (Sandbox Code Playgroud)
我想,我们也需要放在NSFetchedresultController后台线程下。因此,我们进行如下修改。
let backgroundContext = persistentContainer.newBackgroundContext()
let controller = NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: backgroundContext,
sectionNameKeyPath: nil, cacheName: nil)
controller.delegate = fetchedResultsControllerDelegate
backgroundContext.perform {
// Perform the fetch.
do {
// This statement tooks some time to complete if you have a lot of rows.
try controller.performFetch()
} catch {
fatalError("Unresolved error \(error)")
}
}
Run Code Online (Sandbox Code Playgroud)
UI 在获取过程中具有响应能力,一段时间后即可获取并显示数据。
但是,如果我们使用启动参数进一步调查
-com.apple.CoreData.ConcurrencyDebug 1
Run Code Online (Sandbox Code Playgroud)
controller.performFetch()执行完成后我们会遇到以下崩溃。
CoreData`+[NSManagedObjectContext __Multithreading_Violation_AllThatIsLeftToUsIsHonor__]:
Run Code Online (Sandbox Code Playgroud)
NSFetchedResultController我想知道,当我们用来加载大量数据(根据测试,只有几百万行)时,是否可以使 UI 响应?可以NSFetchedResultController在后台线程下运行吗?
我认为您的问题可能是fetchedResultsControllerDelegate新控制器的分配。这似乎可以从您遇到多线程违规的地方推断出来。
从您提供的代码来看,尚不清楚委托是什么类型的对象,但推测它管理 UI,因此位于主线程上。您可以看到谁这可能会导致线程问题。
感谢您从我的答案中发布到此问题的链接/sf/answers/1029733281/。datasource我仍然认为,如果您在完成后将FRC 指定为您的表,然后reloadData.
附带说明:虽然我发现这个问题从工程角度来看很有趣且具有挑战性,但我怀疑直接在移动设备上处理数百万条记录是否是一个好的架构。
| 归档时间: |
|
| 查看次数: |
326 次 |
| 最近记录: |