Core Data + Gran Central Dispatch
Core Data has a particular strategy to support multi-threading named Use Thread Confinement, this strategy is well explained in the Apple documentation but it reduces to the three following rules:
1.- Have only one NSPersistentStoreCoordinator per app
2.- Create one NSManagedObjectContext per thread
3.- Do not pass NSManagedObject instances between threads
In the following example I am assuming that you create a data model with the object Person:
// 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
Written by Juan Karam
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Core data
Authors
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#