Core Data + Gran Central Dispatch

Core Data tem uma estratégia particular para suportar multi-threading chamada Use Thread Confinement . Essa estratégia é bem explicada na documentação da Apple, mas se reduz às três seguintes regras:

1.- Tenha apenas um NSPersistentStoreCoordinator por aplicativo

2.- Crie um NSManagedObjectContext por thread

3.- Não passe instâncias NSManagedObject entre threads

No exemplo a seguir, estou assumindo que você cria um modelo de dados com o objeto Pessoa :

// Create a new background queue for GCD
dispatch_queue_t backgroundDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

// Dispatch the following code on our background queue
dispatch_async
(backgroundDispatchQueue,
^{
// Because at this point we are running in another thread we need to create a
// new NSManagedContext using the app's persistance store coordinator
NSManagedObjectContext *backgroundThreadContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
[backgroundThreadContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];

// Now we can create a new object using the NSManagedContext of this thread
Person *backgroundThreadPerson = [NSEntityDescription insertNewObjectForEntityForName:@"Person"
inManagedObjectContext
:backgroundThreadContext];
backgroundThreadPerson
.name = @"Juan";


// Is very important that you save the context before moving to the Main Thread,
// because we need that the new object is writted on the database before continuing
NSError *error;

if(![backgroundThreadContext save:&error])
{
NSLog(@"There was a problem saving the context. With error: %@, and user info: %@",
[error localizedDescription],
[error userInfo]);
}


// Now let's move to the main thread
dispatch_async
(dispatch_get_main_queue(), ^
{
// If you have a main thread context you can use it, this time i will create a
// new one
NSManagedObjectContext *mainThreadContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
[mainThreadContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];

NSError *error;

// Retreive the new person object in the main thread using the Core Data Object ID
Person *mainThreadPerson = (Person *)[mainThreadContext existingObjectWithID:[backgroundThreadPerson objectID] error:&error];

// We need to check that the operation was successfull
if(mainThreadPerson == nil)
{
NSLog(@"There was a problem retrieving a Managed Object. With error: %@, and user info: %@",
[error localizedDescription],
[error userInfo]);
}

// This prints "Juan"
NSLog(@"%@", mainThreadPerson.name);
});
});

Prost!

JK