I've been experimenting with the core data setup recommended by Marcus Zarra's core data book. The setup entails two managed object contexts. A parent moc with concurrency type private. And a child main context. The stated reasoning behind this is that the main core data context can have super fast reads/writes since changes on the main context (on main queue) are propagated up to the parent, and not to disk.
However Zarra's core data initialization method sets up each context on the same thread. Since performblock* methods are executed on the same queue that the managedobjectcontext was created on, it sounds like all core data reads/writes are going to happen on the main queue. Wouldn't this stack be better served by setting up the private context on a background thread?
That thought led me to write code (inspired by code in Zarra's book) resembling the following:
__block NSManagedObjectContext *private = nil;
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSPersistentStoreCoordinator *psc = nil;
psc = [self persistentStoreCoordinator];
NSUInteger type = NSPrivateQueueConcurrencyType;
private = [[NSManagedObjectContext alloc] initWithConcurrencyType:type];
[private setPersistentStoreCoordinator:psc];
});
NSManagedObjectContext *moc = nil;
type = NSMainQueueConcurrencyType;
moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:type];
[moc setParentContext:private];
_mainManagedObjectContext = moc;
_backgroundObjectContext = private;
...
When I set up my core data stack like this, I end up with a deadlock coming from performBlockAndWait as the main thread waits for itself to free up in order to execute that block of work...ad infinitum. Strangely, the queue i am attempting to perform work on is not just any global queue--it's the main thread. For some reason, dispatch_sync with one of the built-in global queues (or for a dispatch_queue i create myself) does not guarantee that the thread used for the chosen block of work will be a thread other than the main thread. Is there anyway other than going lower than gcd (e.g. using nsthread etc...) to guarantee that the block will be executed on a thread other than the main thread.