【发布时间】:2017-06-13 19:49:56
【问题描述】:
我有一个使用 Core Data 的应用程序,它具有以下相当标准的托管对象上下文层次结构:
Persistent Store Coordinator
↳ Save Context (Private Queue Concurrency Type)
↳ Main Context (Main Queue Concurrency Type)
↳ Private Context (Private Queue Concurrency Type)
所有托管对象上下文的合并策略设置为NSMergeByPropertyObjectTrumpMergePolicy
我正在观察NSManagedObjectContextDidSaveNotification,它会在保存私有上下文并将更改合并到主上下文时调用以下函数:
func contextDidSaveNotificationHandler(notification: NSNotification) {
if let savedContext = notification.object as? NSManagedObjectContext {
if savedContext == privateObjectContext {
mainObjectContext.performBlock({
if let updatedObjects = notification.userInfo![NSUpdatedObjectsKey] as? Set<NSManagedObject> {
//
// fire faults on the updated objects
//
for obj in updatedObjects {
mainObjectContext.objectWithID(obj.objectID).willAccessValueForKey(nil)
}
}
mainObjectContext.mergeChangesFromContextDidSaveNotification(notification)
})
}
}
}
这在大多数情况下都有效,但有时我发现私有上下文中现有对象的更改没有合并到主上下文中。我不知道为什么——私有上下文保存成功;正在发送NSManagedObjectContextDidSaveNotification 通知;正在调用通知处理程序; notification.userInfo?[NSUpdatedObjectsKey] 包含正确更新的对象;但最后,主上下文与私有上下文不同步。 (即:主上下文中的托管对象与notification.userInfo?[NSUpdatedObjectsKey] 中包含的值不同步)如果我终止应用程序并重新启动它,上下文将再次同步(从持久存储加载对象后)。
我在启动参数中启用了-com.apple.CoreData.ConcurrencyDebug 1,并且所有核心数据多线程规则都被遵循。我看不到托管对象上下文层次结构或合并功能有任何明显错误。这可能是什么原因造成的?
【问题讨论】:
-
您如何测试主上下文中的托管对象不同步?
-
如果您只支持 iOS 10+,那么您可以使用 automaticallyMergesChangesFromParent 来为您处理。
-
if savedContext == privateObjectContext {行中的privateObjectContext是主上下文的父级还是兄弟级? -
我通过在调用
mainObjectContext.mergeChangesFromContextDidSaveNotification(notification)之前和之后记录对象(使用mainObjectContext.objectWithID(_:))来测试它们是否不同步。我还记录了notification.userInfo?[NSUpdatedObjectsKey]值,因为它们代表私有上下文中对象的状态。而 privateObjectContext 是主上下文的兄弟