Changes saved from one NSManagedObjectContext doesn't reflect on main NSManagedObjectContext
Asked Answered
F

1

15

I have a main NSManagedObjectContext that's created in the appDelegate.

Now, I'm using another NSManagedObjectContext for editing/adding new objects without affecting the main NSManagedObjectContext, until I save them.

When I save the second NSManagedObjectContext, the changes are not reflected in the main NSManagedObjectContext, yet if I open the .sqlite database from simulator, the changes have been saved correctly into the .sqlite database. It doesn't matter if I fetch the data again, or even if I create a third NSManagedObjectContext, I cannot see those changes from the second NSManagedObjectContext, despite the fact those changes do actually exist on disk at this point.

If I quit and re-open the app, all changes are there.

What can cause the main NSManagedObjectContext to not see the new changes present in the persistent store?

Before this approach, I was using a single NSManagedObjectContext and undoManager, but I wanted to change it to use two different NSManagedObjectContexts.

The second NSManagedObjectContext save:

    NSError* error = nil;

    if ([managedObjectContext hasChanges]) {
        NSLog(@"This new object has changes");
    }

    if (![managedObjectContext save:&error]) {
        NSLog(@"Failed to save to data store: %@", [error localizedDescription]);
        NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
        if(detailedErrors != nil && [detailedErrors count] > 0) {
            for(NSError* detailedError in detailedErrors) {
                NSLog(@"  DetailedError: %@", [detailedError userInfo]);
            }
        }
        else {
            NSLog(@"  %@", [error userInfo]);
        }
    }
Funny answered 27/5, 2011 at 14:39 Comment(0)
O
28

If you haven't already done so, I suggest reading the Apple documentation on Core Data : Change Management.

You need to notify the first context of the changes that were saved through the second context. When saving a context, it posts a NSManagedObjectContextDidSaveNotification. Register for that notification. In the handler method, merge into the first context the changes saved through the second context. For example:

// second managed object context save

// register for the notification
[[NSNotificationCenter defaultCenter] 
    addObserver:self 
       selector:@selector(handleDidSaveNotification:)
           name:NSManagedObjectContextDidSaveNotification 
         object:secondManagedObjectContext];

// rest of the code ommitted for clarity
if (![secondManagedObjectContext save:&error]) {
    // ...
}

// unregister from notification
[[NSNotificationCenter defaultCenter] 
    removeObserver:self 
              name:NSManagedObjectContextDidSaveNotification 
            object:secondManagedObjectContext];

Notification handler:

- (void)handleDidSaveNotification:(NSNotification *)note {
    [firstManagedObjectContext mergeChangesFromContextDidSaveNotification:note];
}
Outbid answered 27/5, 2011 at 16:8 Comment(4)
I thought the NSManagedObjectContextDidSaveNotification was not necessary/mandatory, I've read other posts and that was not clear to me. I'll try what you suggest and post here again. Thanks!Funny
+1! Also there is a good article on cocoanetics explaining how to work with multiple contexts and core data that is worth reading cocoanetics.com/2012/07/multi-context-coredataKillifish
handleDidSaveNotification can be avoided, and instead just add the observer on firstManagedObjectContext, ...addObserver: firstManagedObjectContext selector:@selector(mergeChangesFromContextDidSaveNotification:)...Enthusiastic
Works perfect also with a privateQueueConcurrencyType. ThanksCioffred

© 2022 - 2024 — McMap. All rights reserved.