Core Uniquing de datos no funciona?

Tengo problemas con los objects duplicates de la misma entidad en un solo context cuando uso dos contexts de objects gestionados.

Considere el siguiente código:

[childMOC performBlockAndWait:^{ // CREATE PERSON IN CHILD MOC Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:childMOC]; person.name = @"Ben"; // SAVE CHILD MOC TO PUSH CHANGES TO MAIN MOC [childMOC save:nil]; NSManagedObjectID *personID = person.objectID; [mainMOC performBlockAndWait:^{ // SAVE MAIN MOC TO PERSIST THE PERSON AND REPLACE ID TO PERMANENT [mainMOC save:nil]; // GET THE PERSON IN THE MAIN MOC Person *personInMainContext = (Person*)[mainMOC objectWithID:personID]; // GET THE PERSON'S NEW PERMANENT ID NSManagedObjectID *personIdAfterSaveToPersistentStore = personInMainContext.objectID; [childMOC performBlockAndWait:^{ // GET THE PERSON IN THE CHILD MOC WITH ITS NEW PERMANENT ID // (this is common when sending the id from mainMOC to childMOC) Person *samePersonFetchedFresh = (Person*)[childMOC objectWithID:personIdAfterSaveToPersistentStore]; // THE PERSON OBJECTS SHOULD BE EXACTLY THE SAME BECAUSE THE MOC GUARANTEES UNIQUING samePersonFetchedFresh.name = @"Jerry"; NSLog(@"%@ & %@", person.name, samePersonFetchedFresh.name); // OUTPUT: Ben & Jerry // NOT THE SAME?! }]; }]; }]; 

Esto significa que un object creado en el MOC hijo pierde su capacidad de uniquing cuando se ha guardado en el MOC principal / almacén persistente.

¿Alguien puede explicar por qué uniquing no funciona en esta situación?

Intenta actualizar tu persona antes de ingresar su nombre. Creo que el uniquing funciona, pero la invalidation del caching podría no ser así.

En algún lugar, debe escuchar el context principal NSManagedObjectContextDidSaveNotification , y propagar los cambios al context (es) secundario (s) usando mergeChangesFromContextDidSaveNotification .

Si una combinación completa no se adapta a sus necesidades, también puede actualizar cada entidad individualmente con refreshObject:mergeChanges:

De una forma u otra, tiene que propagar los cambios si no quiere tratar con instancias actualizadas y copys antiguas.

Esto no se hace automáticamente, y esto es para bien, ya que la operación puede ser bastante pesada. Debe manejar las combinaciones cuando corresponda, para los contexts relevantes. Por ejemplo, si está rellenando su database con algún service JSON, utilizará un context para agregar entidades a la database, y querrá actualizar la interfaz de usuario cuando los datos sean consistentes y no cada vez que guarde algo en la database. context principal y tal vez al disco también. Del mismo modo, ese context ciertamente no está interesado en los cambios realizados en la interfaz de usuario y luego se guarda en el context / disco principal. Entonces, el process no es automático.

Mi solución fue:

1) Utilice el MOC de background como el MOC padre y el MOC principal como un niño. Como bonificación, no necesito save el MOC principal para get las identificaciones permanentes.

 [DC.backgroundMOC performBlock:^{ // Add, save and update managed objects [DC saveContext]; // The changes is being pushed to the main context }]; 

2) Utilice NSManagedObjectContextDidSaveNotification para mantener al MOC principal actualizado (el MOC principal está actualizando la UI)

 - (void) backgroundMOCSaved:(NSNotification*)notification { [mainMOC performBlock:^{ [mainMOC mergeChangesFromContextDidSaveNotification:notification]; }]; }