Core Data managed object context thread synchronisation

core-data, iphone

Solution

If you save the background context on the background thread and then listen for `NSManagedObjectContextObjectsDidChangeNotification` on the main thread you can call `-mergeChangesFromContextDidSaveNotification:` on the main context (on the main thread) and the changes will show up as soon as you perform the save on the background thread.

Problem

I'm have an issue where i'm updating a many-to-many relationship in a background thread, which works fine in that threa, but when I send the object back to the main thread the changes do not show. If I close the app and reopen the data is saved fine and the changes show on the main thread. Also using [context lock] instead of a different managed object context works fine. I have tried NSManagedObjectContext: ``` - (BOOL)save:(NSError **)error; - (void)refreshObject:(NSManagedObject *)object mergeChanges:(BOOL)flag; ``` at different stages throughout the process but it doesn't seem to help. My core data code uses the following getter to ensure any operations are thread safe: ``` - (NSManagedObjectContext *) managedObjectContext { NSThread * thisThread = [NSThread currentThread]; if (thisThread == [NSThread mainThread]) { //Main thread just return default context return managedObjectContext; } else { //Thread safe trickery NSManagedObjectContext * threadManagedObjectContext = [[thisThread threadDictionary] objectForKey:CONTEXT_KEY]; if (threadManagedObjectContext == nil) { threadManagedObjectContext = [[[NSManagedObjectContext alloc] init] autorelease]; [threadManagedObjectContext setPersistentStoreCoordinator: [self persistentStoreCoordinator]]; [[thisThread threadDictionary] setObject:threadManagedObjectContext forKey:CONTEXT_KEY]; } return threadManagedObjectContext; } } ``` and when I pass object between threads i'm using ``` -(NSManagedObject*)makeSafe:(NSManagedObject*)object { if ([object managedObjectContext] != [self managedObjectContext]) { NSError * error = nil; object = [[self managedObjectContext] existingObjectWithID:[object objectID] error:&error]; if (error) { NSLog(@"Error makeSafe: %@", error); } } return object; } ``` Any help appreciated

Original source