I have an application using Core Data with the following, fairly standard, managed object context hierarchy:
Persistent Store Coordinator
↳ Save Context (Private Queue Concurrency Type)
↳ Main Context (Main Queue Concurrency Type)
↳ Private Context (Private Queue Concurrency Type)
The merge policy for all managed object contexts is set to NSMergeByPropertyObjectTrumpMergePolicy
I am observing NSManagedObjectContextDidSaveNotification
which will invoke the following function when the Private Context is saved and merge changes to the Main Context:
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)
})
}
}
}
This is working most of the time but sometimes I am finding that changes to existing objects in the Private Context are not being merged into the Main Context. I can't figure out why -- the private context save is successful; the NSManagedObjectContextDidSaveNotification
notification is being sent; the notification handler is being invoked; notification.userInfo?[NSUpdatedObjectsKey]
contains the correctly updated objects; but at the end, the main context is not synchronized with the private context. (ie: the managed objects in the main context are not in sync with the values contained in notification.userInfo?[NSUpdatedObjectsKey]
) If I kill the app and relaunch it, the contexts become synchronized again (after loading objects from the persistent store).
I have -com.apple.CoreData.ConcurrencyDebug 1
enabled in my launch arguments, and all Core Data multithreading rules are being followed. I can't see anything overtly wrong with my managed object context hierarchy or the merging function. What could possibly be causing this?