I’m having problems with duplicate objects of the same entity within a single context when using two managed object contexts.
Consider the following code:
[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?!
}];
}];
}];
This means that an object created in the child MOC loose its uniquing ability when it has been saved in the main MOC / persistent store.
Can anyone explain why uniquing doesn’t work in this situation?
My solution was to:
1) Use the background MOC as the parent MOC and the main MOC as a child. As a bonus I don’t need to save the main MOC to get the permanent IDs.
2) Use NSManagedObjectContextDidSaveNotification to keep the main MOC up to date (the main MOC is updating the UI)