mainMOC
is the primary managed object context
editorMOC
is a managed object context created in editorViewController
with an undo manager so the user can edit a single managed object
after editorMOC
saves, mainMOC
refreshes the updated managed object in the notification handler for NSManagedObjectContextDidSaveNotification
In the save handler, if I use [mainMOC refreshObject:obj mergeChanges:YES]
the updates to the object are not reflected in mainMOC
post-refresh. If I use [mainMOC refreshObject:obj mergeChanges:NO]
the object is invalidated and at the next fault the changes are reflected in the data loaded from the store.
QUESTION: Why would the object not reflect the update when mergeChanges:YES
is specified?
I have a core data based app with multiple managed object contexts. The app is complicated and proprietary so I cannot simply share code directly from the app. I have created a simple test app in an attempt to reproduce my issue but the test app doesn't exhibit the problem. I have not been able to find a logical difference between the implementations. I apologize for not posting sample code, I believe I explained the implementation well below. If something is not clear, please ask in the comments and I will do my best to clarify.
Here's my situation. Everything described below is running on the main thread.
The app has a primary managed object context called mainMOC
that is accessed on the main thread and used with NSFetchedResultsControllers
to display data in various table views.
I have a view controller called EditorViewController
that allows editing of an existing object of a particular entity. This view controller creates it's own managed object context called editorMOC
using the same persistent store coordinator with an undo manager so changes can be rolled back or saved when dismissing the editor.
EditorViewController
is observing the NSManagedObjectContextDidSaveNotification
. When this notification occurs, the notification handler calls [_mainMOC mergeChangesFromContextDidSaveNotification:notification]
to merge the changes from editorMOC
into mainMOC
.
The table view controller that uses an NSFetchedResultsController
is handling the controller delegate messages.
I have added NSLog output to look at look at what happens in all of the above steps and I have verified the following:
NSManagedObjectContextDidSaveNotification
is called and that the updated object is included.controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
protocol message.mainMOC
is not reflecting the updates and that the updated object has not been invalidated by mergeChangesFromContextDidSaveNotification:
.For reference, both my main app and test app implement the above functionality but the test app shows the updates merged correctly and the main app does not.
I am looking for suggestions on what would cause mergeChangesFromContextDidSaveNotification:
not to successfully merge and/or invalidate the updated object.
Thanks!
The fetched results controller does not receive the controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
delegate message. Instead it sends it to the delegate in response to a change in the context. If that delegate message is being sent and does contain the proper object, then the main context is aware of the changes.
If so, then your error is most likely in the the code interfacing the fetched results controller and the tableview. Something is preventing the object from appearing correctly.
The issue I had that caused mergeChangesFromContextDidSaveNotification not to work was I created a new NSPersistentStoreCoordinator for each new NSManagedObjectContext. When I shared NSPersistentStoreCoordinator between all MOCs, mergeChangesFromContextDidSaveNotification works perfectly. Also, make sure mergeChangesFromContextDidSaveNotification is called on the thread that owns the MOC.
From the research I did, it is safe to share NSPersistentStoreCoordinator between threads for use with NSManagedObjectContext. NSManagedObjectContext will lock the persistent store as necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With