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