Reputation: 24902
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;
}
Upvotes: 0
Views: 387
Reputation: 70936
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.
Upvotes: 1
Reputation: 80265
After creating the NSManagedObjectContext
you have to assign the parent context if you need it to be a child context.
[newContext setParentContext:mainThreadManagedObjectContext];
In this case you do not even have to assign the persistent store. From the docs:
Rather than specifying a persistent store coordinator for a managed object context, you can now specify a parent managed object context using setParentContext:. This means that fetch and save operations are mediated by the parent context instead of a coordinator.
Upvotes: 1