when and why to use multiple NSManagedObjectContext?

core-data, ios

Solution

Typically, you want to use a separate `NSManagedObjectContext` for each thread that will access the Core Data db. This is to prevent the object graphs from potentially getting into an inconsistent state due to concurrent writes to the same context.

The simplest way to handle this is to create a new `NSManagedObjectContext` for each thread and share a single `NSPersistentStoreCoordinator`.

Create a property in your AppDelegate of type `NSManagedObjectContext` and override the getter to return a new context for each calling thread. Do this by utilizing the `threadDictionary` of each thread.

First, set up your managedObjectModel and persistentStoreCoordinator as you normally would. Then create your context in your AppDelegate and assign to your property:

self.managedObjectContext = [[NSManagedObjectContext alloc] init];
self.managedObjectContext.persistentStoreCoordinator = self.storeCoordinator;

In your managedObjectContext getter override, use the following code to return a separate context for each calling thread:

- (NSManagedObjectContext *) managedObjectContext
{
    NSThread *thisThread = [NSThread currentThread];
    if (thisThread == [NSThread mainThread])
    {
        //For the Main thread just return default context iVar      
        return _managedObjectContext;
    }
    else
    {
        //Return separate MOC for each new thread        
        NSManagedObjectContext *threadManagedObjectContext = [[thisThread threadDictionary] objectForKey:@"MOC_KEY"];
        if (threadManagedObjectContext == nil)
        {
            threadManagedObjectContext = [[[NSManagedObjectContext alloc] init];
            [threadManagedObjectContext setPersistentStoreCoordinator: [self storeCoordinator]];
            [[thisThread threadDictionary] setObject:threadManagedObjectContext forKey:@"MOC_KEY"];

        }

        return threadManagedObjectContext;
    }
}

Now anywhere in your code where you access the managedObjectContext property of the AppDelegate, you will be sure to be thread safe.

Problem

Basically, I have only used one moc in my app, but I think I should use multiple NSManagedObjectContext in some cases. - when I should use multiple NSManagedObjectContext? - I have heard that I should use 3 moc in some cases, but I don't know which cases I should use 3 moc?

Original source