Literature seems a bit sparse at the moment about the new NSManagedObjectContext concurrency types. Aside from the WWDC 2011 vids and some other info I picked up along the way, I'm still having a hard time grasping how each concurrency type is used. Below is how I'm interpreting each type. Please correct me if I'm understanding anything incorrectly.
NSConfinementConcurrencyType
This type has been the norm over the last few years. MOC's are shielded from each thread. So if thread A MOC wants to merge data from Thread B MOC via a save message, thread A would need to subscribe to thread B's MOC save notification.
NSPrivateQueueConcurrencyType
Each MOC tree (parent & children MOCs) share the same queue no matter what thread each is on. So whenever a save message from any of these contexts is sent, it is put in a private cue specifically made only for this MOC tree.
NSMainQueueConcurrencyType
Still confused by this one. From what I gather it's the like NSPrivateQueueConcurrencyType, only the private queue is run on the main thread. I read that this is beneficial for UI communications with the MOC, but why? Why would I choose this over NSPrivateQueueConcurrencyType? I'm assuming that since the NSMainQueueConcurrencyType is executed in the main thread, does this not allow for background processes? Isn't this the same as not using threads?
midas06 wrote:
I understood it to be the other way around: you put the parent context on the main thread using NSMainQueueConcurrencyType and the child context on the background thread using NSPrivateQueyeConcurrencyType. Am I wrong?
I think the answers are in the note : Core Data Release Notes for Mac OS X Lion http://developer.apple.com/library/mac/#releasenotes/DataManagement/RN-CoreData/_index.html
For NSPrivateQueueConcurrencyType, I think you are not right. A child context created with this concurrency type will have its own queue. The parent/child context is not entirely related to threading. The parent/child seems to simplify communication between contexts. I understand that you just have to save changes in the child contexts to bring them back in the parent context (I have not tested it yet). Usually parent/child context pattern are related to main queue/background queue pattern but it is not mandatory. [EDIT] It seems that access to the store (Save and Load) are done via the main context (in the main queue). So it is not a good solution to perform background fetches as the query behind executeFetchRequest will always be performed in the main queue.
For NSMainQueueConcurrencyType, it is the same as NSPrivateQueueConcurrencyType, but as it is related to main queue, I understand that you perform operation with the context without necesseraly using performBlock ; if you are in the context of the main queue, in View controller delegate code for example (viewDidLoad, etc).
The queue concurrency types help you to manage mutlithreaded core data:
For both types, the actions only happen on the correct queue when you do them using one of the performBlock methods. i.e.
The private queue concurrency type does all it's work in a background thread. Great for processing or disk io.
The main queue type just does all it's actions on a UIThread. That's neccesary for when you need to do things like bind a NSFetchedResultsController up to it, or any other ui related tasks that need to be interwoven with processing that context's objects.
The real fun comes when you combine them. Imagine having a parent context that does all io on a background thread that is a private queue context, and then you do all your ui work against a child context of the main queue type. Thats essentially what UIManagedDocument does. It lets you keep you UI queue free from the busywork that has to be done to manage data.