I'm a beginner with Grand Central Dispatch (GCD) and Core Data, and I need your help to use Core Data with CGD, so that the UI is not locked while I add 40.000 records to Core Data.
I know that CD is not thread safe, so I have to use another context, and then save the data and merge contexts, as far as I was able to understand from some articles.
What I couldn't do yet, is put the pieces together.
So, in my code, I need your help on how to to that.
I have:
/*some other code*/
for (NSDictionary *memberData in arrayWithResult) {
//get the Activities for this member
NSArray *arrayWithMemberActivities = [activitiesDict objectForKey:[memberData objectForKey:@"MemberID"]];
//create the Member, with the NSSet of Activities
[Members createMemberWithDataFromServer:memberData
andActivitiesArray:arrayWithMemberActivities
andStaffArray:nil
andContactsArray:nil
inManagedObjectContext:self.managedObjectContext];
}
How can I transform this to work on the background, and then, when done saving, save the data and update the UI, without blocking the UI while saving the 40.000 objects?
Here's a good example for you to try. Feel free to come back if you have any questions:
self.mainThreadContext... // This is a reference to your main thread context
NSPersistentStoreCoordinator *mainThreadContextStoreCoordinator = [self.mainThreadContext persistentStoreCoordinator];
dispatch_queue_t request_queue = dispatch_queue_create("com.yourapp.DescriptionOfMethod", NULL);
dispatch_async(request_queue, ^{
// Create a new managed object context
// Set its persistent store coordinator
NSManagedObjectContext *newMoc = [[NSManagedObjectContext alloc] init];
[newMoc setPersistentStoreCoordinator:mainThreadContextStoreCoordinator]];
// Register for context save changes notification
NSNotificationCenter *notify = [NSNotificationCenter defaultCenter];
[notify addObserver:self
selector:@selector(mergeChanges:)
name:NSManagedObjectContextDidSaveNotification
object:newMoc];
// Do the work
// Your method here
// Call save on context (this will send a save notification and call the method below)
BOOL success = [newMoc save:&error];
if (!success)
// Deal with error
[newMoc release];
});
dispatch_release(request_queue);
And in response to the context save notification:
- (void)mergeChanges:(NSNotification*)notification
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.mainThreadContext mergeChangesFromContextDidSaveNotification:notification waitUntilDone:YES];
});
}
And don't forget to remove the observer from the notification center once you are done with the background thread context.
[[NSNotificationCenter defaultCenter] removeObserver:self];