¿Por qué los datos centrales no pueden fusionar datos del context privado al context principal?

Tengo una aplicación que utiliza Core Data con la siguiente jerarquía de context de object gestionado bastante estándar:

Persistent Store Coordinator ↳ Save Context (Private Queue Concurrency Type) ↳ Main Context (Main Queue Concurrency Type) ↳ Private Context (Private Queue Concurrency Type) 

La política de combinación para todos los contexts de object administrado se establece en NSMergeByPropertyObjectTrumpMergePolicy

Estoy observando NSManagedObjectContextDidSaveNotification que invocará la siguiente function cuando se guarda el context privado y se combinan los cambios en el context principal:

 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) }) } } } 

Esto funciona la mayor parte del time, pero a veces descubro que los cambios en los objects existentes en el context privado no se combinan en el context principal. No puedo entender por qué: el context privado salvo es exitoso; se NSManagedObjectContextDidSaveNotification notificación NSManagedObjectContextDidSaveNotification ; el manejador de notifications se está invocando; notification.userInfo?[NSUpdatedObjectsKey] contiene los objects correctamente actualizados; pero al final, el context principal no está sincronizado con el context privado. (es decir: los objects gestionados en el context principal no están sincronizados con los valores contenidos en notification.userInfo?[NSUpdatedObjectsKey] ) Si notification.userInfo?[NSUpdatedObjectsKey] la aplicación y la relanza, los contexts se vuelven a sincronizar (después de cargar objects del almacén persistente) .

Tengo -com.apple.CoreData.ConcurrencyDebug 1 habilitado en mis arguments de inicio y se siguen todas las reglas de multiprocess de Core Data. No puedo ver nada abiertamente mal con mi jerarquía de context de object gestionado o la function de fusión. ¿Qué podría estar causando esto?

No puedes fusionar el context hermano. Tienes que unirte desde el padre hacia abajo. En otras palabras, cambie

  if savedContext == privateObjectContext { 

a

  if savedContext == savingObjectContext { 

donde el savingObjectContext es el context principal del context principal.

Siempre puede configurar su principalQueueContext como el principal de su privateQueueContext:

 privateObjectContext.parent = mainObjectContext 

Esto fusionará sus guardados en su context de object principal. Utilicé esto en un proyecto en el que analizo JSON y establezco los objects de datos básicos en el bloque de ejecución de un privateQueue, con mi mainContext establecido como el principal. Luego simplemente guardé el privado y luego accedí a los datos del hilo principal / context principal. Funciona de maravilla. Debería agregar que no guardo el context privado en la memory, se crea nuevo cuando lo necesito.

El problema es con su política de combinación. Intente cambiar a NSErrorMergePolicy y creo que comenzará a ver conflictos de fusión. Como mínimo, esto le dará más de una idea de la causa subyacente