2

In an app that I am working on I need to access and write to Core Data at the same time. I have been able to gather that this means that I need to user multiple managedObjectContexts but I don't understand how I am supposed to setup those two managedObjectContexts.

I understand that once I have them setup I need to do the write operations on a background thread on its managedObjectContext and then merge the data through an operation like this: Core Data and threads / Grand Central Dispatch .

So my question is, how would I go about initiating two separate managedObjectContexts so that I can then use them as described?

Community
  • 1
  • 1
harryisaac
  • 1,121
  • 1
  • 10
  • 18
  • interesting question, why do you need two MOC ? – DogCoffee Oct 01 '13 at 04:29
  • From what I understand the reason is that the managedObjectContexts are not thread safe and so you need to have two for each thread, one to just read on the main thread and another to do writes to on the background thread. Then when your done writing you merge the two which makes it so that you can do large tasks in the background threads without stoping user interaction. – harryisaac Oct 02 '13 at 03:29
  • i'll check it out.cheers – DogCoffee Oct 02 '13 at 03:31

2 Answers2

1

You have to create two separate NSManagedObjectContexts with the same NSPersistentStoreCoordinator like this,

First create two NSManagedObjectContexts name as backgroundManagedObjectContext and mainBackgroundManagedObjectContext in your model class like this

+ (NSManagedObjectContext *)backgroundManagedObjectContext
    {
        static NSManagedObjectContext * backgroundManagedObjectContext;
        if(backgroundManagedObjectContext != nil){
            return backgroundManagedObjectContext;
        }
        @try {
            NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
            if (coordinator != nil) {
                backgroundManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
                [backgroundManagedObjectContext setPersistentStoreCoordinator: [self persistentStoreCOordinator]];
            }
        }
        @catch (NSException *exception) {
            NSLog(@"Exception occur %@",exception);
        }
        return backgroundManagedObjectContext;

    }

then both will need get the same persistentStoreCoordinator then need to merge your backgroungManagedObjectContext to mainBackgroundManagedObjectContext, for that create NSNotification whenever you save the data into backgroundManageObjectContext like this

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(contextDidSave:)
                                                 name:NSManagedObjectContextDidSaveNotification
                                               object:nil];

then you have to implement this notification method for updating your mainManagedObjectContext like this

- (void)contextDidSave:(NSNotification *)notification
    {
        SEL selector = @selector(mergeChangesFromContextDidSaveNotification:);
        [[self mainManagedObjectContext] performSelectorOnMainThread:selector withObject:notification waitUntilDone:YES];

    }
wesley
  • 859
  • 5
  • 15
0

If you really want to do concurrent reads and writes, you might be interested in the setup presented during WWDC 2013. It uses two NSPersistentStoreCoordinator's, each with one context. You merge changes between them manually, thus achieving nice, non UI blocking code.

It's described in the following sessions:

  • 207 - What’s New in Core Data (starting from slide number 145).
  • 211 - Core Data Performance (starting from slide number 91),
Arek Holko
  • 8,966
  • 4
  • 28
  • 46