I am using a Private Managed Object Context to create some new objects into the persistent store, then after saving the private MOC, merging them into the main MOC using mergeChangesFromContextDidSaveNotification
. This works fine, and updates the UI as required, and the NSManagedObjectContextWillSaveNotification
is NOT invoked here for the mainMOC
.
Then I make some changes to the mainMOC
using the UI, and listen to NSManagedObjectContextWillSaveNotification
. The notification is posted, but it contains not only the edits I made, but also the objects that were merged in from the PrivateMOC
using mergeChangesFromContextDidSaveNotification
.
Is there a way to ignore the changes that were merged in from another context into the mainContext
, on subsequent contextDidChange
notifications?
Here is the setup:
- (void) loadData {
privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateQueueConcurrencyType];
privateContext.persistentStoreCoordinator = self.mainContext.persistentStoreCoordinator;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextWillSave:)
name:NSManagedObjectContextWillSaveNotification
object: self.mainContext];
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:record.recordType inManagedObjectContext: self.privateContext];
// fill in object
if ([self.privateContext hasChanges]) {
[self savePrivateContextAndMergeWithMainContext: self.privateContext];
}
}
- (void) savePrivateContextAndMergeWithMainContext: (NSManagedObjectContext *) privateContext {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(privateContextDidChange:) name:NSManagedObjectContextDidSaveNotification object:privateContext];
__block NSError *error = nil;
[privateContext performBlockAndWait:^{
NSLog(@"PrivateContext saved");
[privateContext save:&error];
}];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:privateContext];
if (error) {
NSLog(@"error = %@", error);
}
}
- (void) privateContextDidChange: (NSNotification *) notification{
[self.mainContext performBlockAndWait:^{
NSLog(@"merged into mainContext");
[self.mainContext mergeChangesFromContextDidSaveNotification:notification];
}];
}
This works fine and saving the private context and merging into the mainContext
doesn't trigger a contextWillSave
notification. But on editing the data from the UI (on the main MOC) triggers the notification and includes the data that was previously saved using the private MOC.
Hope that's clear. Let me know if I should include anything else.
-- UPDATE --
Seems like the problem is with specifically deleting objects from the private context. After deleting from the private context, and calling mergeChangesFromContextDidSaveNotification
on the main MOC, the mainMoc's deletedObjects
set still shows the object that was deleted. This doesn't happen with inserts or updates in the private context. Is this documented anywhere? What could be the workaround?
mergeChangesFromContextDidSaveNotification:
is called – Vasquez