My approach so far has been something like this:
1- A main context initialized like so:
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model]; if(![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { DDLogModel(@"Unresolved error %@", error.localizedDescription); return; } self.context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; self.context.persistentStoreCoordinator =_persistentStoreCoordinator;
2- Then, as I go about creating core data objects or modifying their relationships concurrently:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSManagedObjectContext *tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType]; tempContext.persistentStoreCoordinator = self.persistentStoreCoordinator; // Do stuff [tempContext save:nil]; });
3- And finally, the main context merge via the
NSManagedObjectContextDidSaveNotification
However, I've recently seen a different approach where for step 2, they instead create a context with NSPrivateQueueConcurrencyType
, make it a child of the main context, and do any work by means of -performBlock:
Is this last approach concurrent by default (even without explicitly dispatching it as such)? Or what's the advantage over the approach I explained?
Another thing that threw me off is that even though the contexts have parentContext
and persistentStoreCoordinator
properties, it appears that setting the latter implies one cannot set the former. That is, a context with a persistent store coordinator actually has that store coordinator as it's parent context?
UPDATE:
Another interesting thing is that with the approach I described above (using GCD), everynow and then when I do [tempContext save:]
I get a weird behaviour: No error is returned (assuming I do pass in an NSError object, unlike in the example), but if I set the generic Objective-C exception pointer on, the background thread does stop there, as if there was an exception. However, if I continue the app does not crash and keeps going and the main moc seems to be just fine.