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?
GCD is built on top of threads. Under the hood, it manages a shared thread pool. With GCD, you add blocks of code or work items to dispatch queues and GCD decides which thread to execute them on. As you structure your code, you'll find code blocks that can run simultaneously and some that should not.
Grand Central Dispatch is used in iOS to introduce concurrency and parallelism in the iOS applications, so that multiple heavy tasks are performed in the background, resulting in the smooth experience of the application usage, as the main thread is unaffected by the heavy background tasks.
In apple document, GCD is Thread-Safe that means multiple thread can access.
Threads. A thread is a sequence of instructions that can be executed by a runtime. Each process has at least one thread. In iOS, the primary thread on which the process is started is commonly referred to as the main thread. This is the thread in which all UI elements are created and managed.
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];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With