Mat*_*ski 28 sqlite cocoa core-data objective-c ios
我正在寻找在后台更新相当大的基于核心数据的数据集的最佳方法,尽可能减少对应用程序UI(主线程)的影响.
这个主题有一些很好的材料,包括:
根据我的研究和个人经验,可用的最佳选择是有效地使用两个单独的核心数据堆栈,这些堆栈仅在数据库(SQLite)级别共享数据.这意味着我们需要两个独立的NSPersistentStoreCoordinators,每个都有它自己的NSManagedObjectContext.通过在数据库上启用预写日志记录(默认从iOS 7开始),几乎在所有情况下都可以避免锁定的需要(除非我们有两个或更多同时写入,这在我的场景中不太可能).
为了进行有效的后台更新并节省内存,还需要批量处理数据并定期保存后台上下文,以便将脏对象存储到数据库并从内存中刷新.可以使用此时NSManagedObjectContextDidSaveNotification生成的结果将背景更改合并到主上下文中,但通常您不希望在保存批处理后立即更新UI.您希望等到后台作业完成并刷新UI(在WWDC会话和objc.io文章中都推荐).这实际上意味着应用程序主上下文在特定时间段内与数据库保持不同步.
所有这些都引出了我的主要问题,即,如果我以这种方式更改数据库,而不立即告诉主要上下文合并更改,那会出现什么问题?我假设它不是所有的阳光都是玫瑰.
我脑子里想到的一个特定情况是,如果后台操作在数据库中删除了该对象,那么如果在主上下文中加载的对象需要满足错误会发生什么?例如,这可能发生在基于NSFetchedResultsController的表视图上,该视图使用batchSize逐步将对象提取到内存中吗?即,尚未完全获取的对象被删除,但我们向上滚动到需要加载对象的点.这是一个潜在的问题吗?其他事情可能会出错吗?我对此事的任何意见表示感谢.
好问题!
即,尚未完全获取的对象被删除,但我们向上滚动到需要加载对象的点.这是一个潜在的问题吗?
不幸的是它会引起问题.将抛出以下异常:
Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0xc544570 <x-coredata://(...)>'
Run Code Online (Sandbox Code Playgroud)
这篇博客文章(标题为"如何与核心数据进行并发?"一节)可能有些帮助,但它并没有用尽这个主题.我正在努力解决我现在正在开发的应用程序中的相同问题,并希望阅读有关它的文章.