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
- Diving into CoreData, again
- Debugging Core Data
- Core Data Notes from iPhone Tech Talk
- Using GDB’s ‘po’ command while a malloc lock is being held
4 Responses 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.
Wid
January 28th, 2011 at 5:30 pm
With this method object are not faulted
So I used the method in
http://www.mlsite.net/blog/?p=518
then every object is correctly faulted but the faults are fetch in Cache so still no update
I had to do
[moc stalenessInterval = 0];
M.Y.
November 20th, 2011 at 12:50 pm
Thank you very much, you saved my day!
Nick Gromov
January 9th, 2012 at 1:46 pm
Thank you very much!