我在一些地方(比如这里的高分答案)读到,将主托管上下文作为后台托管上下文的子级以节省 save() 时间并提高 UI 响应能力是一种很好的做法。
Persistent Store Coordinator
↑
Managed Object Context (for saving) <= note this
↑
Managed Object Context (main)
↑
Managed Object Context (for editing)
但问题是,由 iOS 模板代码创建的主要托管上下文与 Persistent Store Coordinator 相关联,并且似乎没有支持的方式来改变它。我尝试了以下代码:
lazy var persistentContainer: NSPersistentContainer = {
// Template code: create persistent container
// ...
// My code
let saveMOC = container.newBackgroundContext()
container.viewContext.persistentStoreCoordinator = nil
container.viewContext.parent = saveMOC
return container
}()
但得到了一个 NSException:
uncaught exception 'NSInternalInconsistencyException', reason: 'Context already has a coordinator; cannot replace.'
我的问题是:
1)这是否意味着,要实现上述架构,我不能使用 NSPersistentContainer 并且必须使用我自己的代码设置核心数据堆栈?
2)鉴于 NSPersistentContainer 是新的 API,我认为它必须有一些方法来达到相同的效果(在后台线程中保存托管对象的更改)。我想知道它是什么?我正在考虑以下方法,其中 save() 仅在保存上下文中调用,而不是在主上下文中调用。但它更复杂,不像上面的那样自然。有没有更简单的方法?
Persistent Store Coordinator
↑ ↑
Context (main) --merge--> Context (saving)
↑
Context (editing)
更新:再想一想,这种方法不起作用,因为合并是基于通知的。如果在主上下文中未调用 save(),则不会触发任何通知。
嗯,我想知道是否可以创建另一个 mainQueueConcurrencyType 的 NSManagedObjectContext,按照我最初的意愿进行设置,然后用它替换 NSPersistentContainer 创建的那个?
感谢您的任何建议。