Note on Core Data concurrency

After enabling the CoreData concurrency debug argument, -com.apple.CoreData.ConcurrencyDebug 1, I quickly learned that I was doing everything wrong with the new concurrency model. So here are my notes on what’s really going on with the new model.

So first, parent-child contexts. The basic idea is that a child context treats its parent context as the persistent store coordinator, albeit an in-memory one. So, a child context saves its data to the parent. That’s it. The parent is ignorant of the child, until the child hands it some updates.

The main queue and private queue concurrency types simply wrap around gcd queues of the same type. So, if you initialize a context with the main queue type, then you must either 1) give it operations with performBlock: or, 2) message it directly when are on the main thread. A private concurrency type has one choice: give it operations with performBlock:. The second option doesn’t exist because you’ll never (knowingly) be on the same thread as its queue.

The thread-confinment concurrency type is still useful, because its often the case that you will do a whole bunch of processing on one thread. In this case, you might create an NSManagedObjectContext for the purposes of importing.

Even creating a new object (inserting it into a managed object context) requires 1) doing it on the main thread with the main thread context, 2) doing it within a performBlock: or 3) doing it in thread confinement. The third option may be the most natural in some scenarios.

A nice usage scenario thus to tie a private context to a persistent store coordinator, and then make a main queue child context tied to that. Important some new objects can thus be done on a private context that is a child of the main queue context. Saving this new private import context will push changes straight to the main UI thread without hitting disk. This might be exactly what you want. Subsequently saving the main UI thread will push everything up to its parent, the top level private thread, which can then be saved without block the main queue.