My Cocoa/Application has a Managed Object Context on the main thread. When I need to update my data my program will:
- Start a new thread
- Receive new data from a server
- Create a new Managed Object Context
- Send a notification to the main thread in order to merge the two context
This is the function that receive the notification on the main thread
- (void)loadManagedObjectFromNotification:(NSNotification *)saveNotification
{
if ([NSThread isMainThread]) {
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:saveNotification];
} else {
[self performSelectorOnMainThread:@selector(loadManagedObjectFromNotification:) withObject:saveNotification waitUntilDone:YES];
}
}
I do not receive any error. My problem is the merge result, it actually concatenate Managed Objects from both context.
My Entity are a really simple list of attribute and relationship.
Maybe the merge need some instructions in order to understand when an updated Managed Object IS NOT a new one, but a edited version of the first one. I imagine that somewhere I need to specify a way to univocally identify an Entity, (an attribute for example can act like an ID) and something like a merge policy (if 2 managed object represent the same object, take the one with the lastModificationDate more recent).
I just need to understand how to correctly merge the 2 contexts in order to have a single updated copy for each object.
UPDATE 1
The problem is now clear to me. The 2 context has a big difference: the ObjectID. While the context on the main thread fetched the ManagedObjects with the Persistent Store coordinator, the second thread create those object by fetching a remote URL. Even if the objects have the same contents, they will have 2 different objectID.
My objects had already an unique identificator, I could use setObjectId in order to set this value. (Apple documentation says this is NOT a good idea).
See Question&Answers more detail:os