How do you create a NSManagedObjectContext
that has a non nil
parentContext
that runs on a different queue/thread?
UIManagedDocument
's managedObjectContext does have this, but I don't know how to replicate it without using UIManagedDocument
.
This is the code I'm using, which results in a managedObjectContext
whose parentContext
property is nil
.
-(NSManagedObjectContext *)context{
if (_context == nil){
_context = [[NSManagedObjectContext alloc] init];
_context.persistentStoreCoordinator = self.storeCoordinator;
}
return _context;
}
-(NSPersistentStoreCoordinator *) storeCoordinator{
if (_storeCoordinator == nil) {
_storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model];
NSError *err = nil;
if (![_storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.dbURL
options:nil
error:&err ]) {
NSLog(@"Error while adding a Store: %@", err);
return nil;
}
}
return _storeCoordinator;
}
-(NSManagedObjectModel *) model{
if (_model == nil) {
_model = [[NSManagedObjectModel alloc] initWithContentsOfURL:self.modelURL];
}
return _model;
}
You create the child context by just allocating it and setting its parent:
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] init];
[childContext setParentContext:[self managedObjectContext]];
The persistent store coordinator is inherited from the parent context, so this is all you need to create the child. But the parent context must use one of the queue-based concurrency types. That means that your code above creating the context would have to change to something like:
_context = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSMainQueueConcurrencyType];
There's also NSPrivateQueueConcurrencyType
. Which is better depends on your app's design.
The runs on a different queue/thread thing is a different matter though. This is never automatic. Your code runs on whatever queue or thread you call it from. Core Data's direct support is limited to using one of the queue-based concurrency types-- but then you need to make sure to use performBlock:
or performBlockAndWait:
to ensure that the context's operations actually happen on the right queue.