The debate between GCD and NSOperation
basically boils down to the argument of using the highest level of abstraction that provides you with a good solution.
NSOperationQueue
is built on top of GCD, so it must be a higher level of abstraction.
However, GCD is so easy to use in the general case, that I find it is preferable to NSOperationQueue
in many cases.
Now, when you bring CoreData into the mix, I would suggest a third alternative. If you are using iOS 5, then you can use private queue concurrency with your MOC. I find that is a good abstraction, and provides an easy to use interface.
So, I would suggest you simply create a MOC with NSPrivateQueueConcurrencyType
for each thread in which you want to do Core Data. You can choose, based on your application characteristics, whether to share a persistentStoreCoordinator
, or use a separate one. You could even use nested contexts (with a caveat for the insert-side).
Basically, it follows this model...
NSManagedObjectContext *moc = [[NSManagedObjectCotext alloc] initWithConcurrencyType:NSPrivateQueuqConcurrencyType];
moc.parentContext = contextIWantToBeParent;
moc.persistentStoreCoordinator = pscIWant;
[moc performBlock:^{
// Your MOC stuff running on its own private queue
}];
Of course, you must choose one method (either parenting to an existing MOC or attaching to a PSC).
I generally prefer the performBlock
method.
EDIT
Thanks. I read that NSManagedObject isnt thread safe. How would I
create new NSManagedObjects on that private queue? – Helium3
Yes, that is true. However, when you create a MOC with a concurrency type, you are agreeing to a contract that goes something like this.
I, an astute programmer, do solemnly agree to the following Core Data Rules regarding concurrency:
If I use NSConfinementConcurrencyType
, I will only use it while running on the thread that created it.
If I use NSPrivateQueueConcurrencyType
, I will only use the MOC from within either performBlock
or performBlockAndWait
.
If I use NSMainQueueConcurrencyType
, I will only use the MOC from within either performBlock
, performBlockAndWait
, or when I know that I am running on the main thread.
If you follow those rules, then you will be able to use the MOC on other threads.
Specifically, when using performBlock
, the Core Data API will make sure the code is appropriately synchronized.