CoreData and mergeChangesFromContextDidSaveNotification
24
Nov
2009
Update: This is even trickier! Don’t forget thread savety in mergeContextChanges, or it will crash absolutely unpredictable!
This was a tricky one.
If you edit a context in another thread and save it, your main context does not get the change notifications. You can either refetch the data (into a fetchedResultsController for example) OR you use mergeChangesFromContextDidSaveNotification.
But thats kinda weird to understand, because this bends Core Data’s own rules with thread safety. Best I’ll show you an code example:
To clarify, DomainManager is my DAO, just some helpers for working with Core Data, should be clear what the functions do.
And don’t forget to unregister your Notifications on dealloc!
// this is called in an NSOperation, thus it has ITS OWN THREAD!
- (void)parseFunction
{
// basically creates a new context
DomainManager
*dm
= [DomainManager domainManagerWithNewContext
];
// registers for changes on that context
NSNotificationCenter *dnc
= [NSNotificationCenter defaultCenter
];
[dnc addObserver
:self selector
:@selector(mergeContextChanges
:) name
:NSManagedObjectContextDidSaveNotification object
:dm.context
];
// perform your data changes here
// calls [_context save]
[dm saveCurrentContext
];
}
// called in extra thread, we need to make sure it's thread save for main.
- (void)mergeContextChanges
:(NSNotification *)notification
{
SEL selector
= @selector(mergeChangesFromContextDidSaveNotification
:);
[[DomainManager main
].context performSelectorOnMainThread
:selector withObject
:notification waitUntilDone
:YES];
Look at apples CoreDataBooks for another example.
Related posts:
- Multithreading with Core Data
- Core Data Notes from iPhone Tech Talk
- Debugging Core Data
- Get the best performance out of CoreData
- XCode and three20: Let’s refactor again!
1 Response to CoreData and mergeChangesFromContextDidSaveNotification
Brian
March 7th, 2010 at 11:05 pm
Thank you kindly good sir! I have been looking for information on this _forver_. I had been ‘refetching’, but lets face it, thats a bad way since you need to find all of the fetches you used. Fortunately, NSFetchedResultsControllers seem to detect the update and act appropriately. Objects update. And life is great.