Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

when and why to use multiple NSManagedObjectContext?

Tags:

ios

core-data

Basically, I have only used one moc in my app, but I think I should use multiple NSManagedObjectContext in some cases.

  1. when I should use multiple NSManagedObjectContext?
  2. I have heard that I should use 3 moc in some cases, but I don't know which cases I should use 3 moc?
like image 982
NOrder Avatar asked Jul 11 '13 12:07

NOrder


1 Answers

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.

like image 177
Ric Perrott Avatar answered Nov 11 '22 09:11

Ric Perrott