Core Data's NSPrivateQueueConcurrencyType and sharing objects between threads

Solution 1:

When you use NSPrivateQueueConcurrencyType you need to do anything that touches that context or any object belonging to that context inside the -performBlock: method.

Your code above is illegal since you're passing those objects back to the main queue. The new API helps you in solving this, though: You create one context that's associated with the main queue, i.e. with NSMainQueueConcurrencyType:

// Assume we have these two context (They need to be set up. Assume they are.)
NSManagedObjectContext *mainMOC = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType] autorelease];
NSManagedObjectContext *backgroundMOC = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease];

// Now this can safely be called from ANY thread:
[backgroundMOC performBlock:^{
    NSArray *results = [backgroundMOC executeFetchRequest:request error:nil];
    for (NSManagedObject *mo in results) {
        NSManagedObjectID *moid = [mo objectID];
        [mainMOC performBlock:^{
            NSManagedObject *mainMO = [mainMOC objectWithID:moid];
            // Do stuff with 'mainMO'. Be careful NOT to use 'mo'.
        }];
    }
}];

This gets less confusing if you move the inner [mainMOC performBlock:] call into its own method. You may also want to pass an array of object IDs back to the main thread's context in stead of executing a block for each object ID. It depends on your needs.

Solution 2:

As Daniel Eggert explains, this is definitely still the case. The exception is for NSMainQueueConcurrencyType, where you can also use the managed object context and objects safely on the main thread (as well as from other threads via the performBlock mechanism). The usefulness of this cannot be understated!

iOS 5 also introduced the concept of parent contexts, which also hugely simplify background operations and remove the need to worry about using notifications to propogate changes between threads.

The WWDC 2012 video "Session 214 - Core Data Best Practices" goes into a lot more detail on both subjects and is very comprehensive. The video is essential viewing for anyone using Core Data.