CoreData and mergeChangesFromContextDidSaveNotification

I create addManagedObjectContext as an area from scratch for new objects, and then merge the new object into my main ManagedObjectContext in Save, as shown in the CoreDataBooks example.

After you merge your new object, how do you get a short link to it to use when displaying a detailed view?

Do you need to get the fetch result controller to exit and fetch again (as indicated in the CoreDataBooks code)? I assume that the initial identifier of the object when in "addManagedObjectContext" does not remain the same after combining it.

There is no such problem in the Recipes project, because you create and work with a new object in one ManagedObjectContext. Therefore, you have a link to the newly created item to show its detailed view.

From CoreDataBooks:

/** Add controller delegate method; informs the delegate that the add operation has completed, and indicates whether the user saved the new book. */ - (void)addViewController:(AddViewController *)controller didFinishWithSave:(BOOL)save { if (save) { /* The new book is associated with the add controller managed object context. This is good because it means that any edits that are made don't affect the application main managed object context -- it a way of keeping disjoint edits in a separate scratchpad -- but it does make it more difficult to get the new book registered with the fetched results controller. First, you have to save the new book. This means it will be added to the persistent store. Then you can retrieve a corresponding managed object into the application delegate context. Normally you might do this using a fetch or using objectWithID: -- for example NSManagedObjectID *newBookID = [controller.book objectID]; NSManagedObject *newBook = [applicationContext objectWithID:newBookID]; These techniques, though, won't update the fetch results controller, which only observes change notifications in its context. You don't want to tell the fetch result controller to perform its fetch again because this is an expensive operation. You can, though, update the main context using mergeChangesFromContextDidSaveNotification: which will emit change notifications that the fetch results controller will observe. To do this: 1 Register as an observer of the add controller change notifications 2 Perform the save 3 In the notification method (addControllerContextDidSave:), merge the changes 4 Unregister as an observer */ NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter]; [dnc addObserver:self selector:@selector(addControllerContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:addingManagedObjectContext]; NSError *error; if (![addingManagedObjectContext save:&error]) { // Update to handle the error appropriately. NSLog(@"Unresolved error %@, %@", error, [error userInfo]); exit(-1); // Fail } [dnc removeObserver:self name:NSManagedObjectContextDidSaveNotification object:addingManagedObjectContext]; } // Release the adding managed object context. self.addingManagedObjectContext = nil; // Dismiss the modal view to return to the main list [self dismissModalViewControllerAnimated:YES]; } /** Notification from the add controller context save operation. This is used to update the fetched results controller managed object context with the new book instead of performing a fetch (which would be a much more computationally expensive operation). */ - (void)addControllerContextDidSave:(NSNotification*)saveNotification { NSLog(@"addControllerContextDidSave"); NSManagedObjectContext *context = [fetchedResultsController managedObjectContext]; // Merging changes causes the fetched results controller to update its results [context mergeChangesFromContextDidSaveNotification:saveNotification]; } 
+3
iphone core-data
source share
1 answer

Looking at these comments, it seems that they are talking about the results obtained by the controllers. Thus, it would be quite expensive to get the FRC to perform a new selection after you have just changed one object, so you can combine your add context with it to notify it of any changes.

After you save and merge, any managed objects that you refer to in the context of the addition will no longer have the identifier of the temporary object, as they exist in the persistent storage. Therefore, you can remember the identifier and use [applicationContext objectWithID: newBookID] in the main context of the application, just fine, to get the handle to the object you are looking for. This will return the object (with all its changes) in the application context.

After the merge, it is likely that the object exists in memory and does not require a trip to the store. However, even if this is the case, since you are dealing with only one object to display in the detailed view, this is not a problem at all. Moving to storage rather than in context is slower, but obviously a whole bunch of time should happen during your application, and this is unlikely to cause problems if you are not dealing with a lot of data!

Hope this helps!

+2
source share

All Articles