core data with multiple managed object contexts
DESCRIPTION
When using Core Data for persisting app data multiple managed object contexts (MOC) are often required to avoid blocking UI. Typically you would create a background MOC and listen for changes on the main MOC, merging changes as necessary. With iOS 5, MOCs now have parent context and the ability to set concurrency types. These new features greatly simplify dealing with Core Data on background queues. During this presentation Matt will cover the pros and cons of this new method of dealing with Core Data.TRANSCRIPT
![Page 1: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/1.jpg)
Core Datawith multiple managed
object contexts
Photo by Free-Photo-Gallery.org
![Page 2: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/2.jpg)
Core Datawith multiple managed
object contexts
Photo by Free-Photo-Gallery.org
![Page 3: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/3.jpg)
Matt(hew) Morey
matthewmorey.com | @xzolian
Senior Developer at ChaiONETraveler
Boardsport Junkie
![Page 4: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/4.jpg)
Agenda
1)Core Data Basics2)Concurrency Problems3)Concurrency Solutions
![Page 5: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/5.jpg)
Agenda
1)Core Data Basics2)Concurrency Problems3)Concurrency Solutions
![Page 6: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/6.jpg)
Basics
![Page 7: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/7.jpg)
Basics
AppAppAppAppAppApp
NSManagedObjectNSManagedObjectNSManagedObjectNSManagedObjectNSManagedObjectNSManagedObject
NSManagedObjectContextNSManagedObjectContextNSManagedObjectContextNSManagedObjectContextNSManagedObjectContextNSManagedObjectContext
NSPersistentStoreCoordinatorNSPersistentStoreCoordinatorNSPersistentStoreCoordinator NSManagedObjectModelNSManagedObjectModelNSManagedObjectModel
NSPersistentStoreNSPersistentStoreNSPersistentStoreNSPersistentStoreNSPersistentStoreNSPersistentStore
SQLite XML BinaryBinary In Memory Custom
![Page 8: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/8.jpg)
Basics
AppAppAppAppAppApp
NSManagedObjectNSManagedObjectNSManagedObjectNSManagedObjectNSManagedObjectNSManagedObject
NSManagedObjectContextNSManagedObjectContextNSManagedObjectContextNSManagedObjectContextNSManagedObjectContextNSManagedObjectContext
NSPersistentStoreCoordinatorNSPersistentStoreCoordinatorNSPersistentStoreCoordinator NSManagedObjectModelNSManagedObjectModelNSManagedObjectModel
NSPersistentStoreNSPersistentStoreNSPersistentStoreNSPersistentStoreNSPersistentStoreNSPersistentStore
SQLite XML BinaryBinary In Memory Custom
![Page 9: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/9.jpg)
Managed Object Model
![Page 10: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/10.jpg)
Managed Object Model
![Page 11: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/11.jpg)
Managed Object Model- (NSManagedObjectModel *)managedObjectModel{ if (_managedObjectModel != nil) { return _managedObjectModel; } NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"core-data" withExtension:@"momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return _managedObjectModel;}
![Page 12: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/12.jpg)
Persistent Store Coordinator
![Page 13: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/13.jpg)
Persistent STore Coordinator- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{ if (_persistentStoreCoordinator != nil) { return _persistentStoreCoordinator; } NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"core-data.sqlite"]; NSError *error = nil; _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { /* Replace this implementation with code to handle the error appropriately. ... */ NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return _persistentStoreCoordinator;}
![Page 14: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/14.jpg)
Persistent STore Coordinator- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{ if (_persistentStoreCoordinator != nil) { return _persistentStoreCoordinator; } NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"core-data.sqlite"]; NSError *error = nil; _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { /* Replace this implementation with code to handle the error appropriately. ... */ NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return _persistentStoreCoordinator;}
![Page 15: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/15.jpg)
Managed Object Context
![Page 16: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/16.jpg)
Managed Object Context- (NSManagedObjectContext *)managedObjectContext{ if (_managedObjectContext != nil) { return _managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) { _managedObjectContext = [[NSManagedObjectContext alloc] init]; [_managedObjectContext setPersistentStoreCoordinator:coordinator]; } return _managedObjectContext;}
![Page 17: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/17.jpg)
Single Context
![Page 18: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/18.jpg)
Single Context
![Page 19: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/19.jpg)
Single Context
Code Examplehttps://github.com/mmorey/CoreDataMultiContext/tree/blocking
![Page 20: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/20.jpg)
Agenda
1)Core Data Basics2)Concurrency Problems3)Concurrency Solutions
![Page 21: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/21.jpg)
Problems
‣Core Data Managed Objects are not thread safe‣Must pass Object IDs to use across threads
‣Objects are locked for all operations including read‣Objects that feed the UI must be fetched on the main thread
![Page 22: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/22.jpg)
Agenda
1)Core Data Basics2)Concurrency Problems3)Concurrency Solutions
![Page 23: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/23.jpg)
Traditional Multi-Context
Pre-iOS 5: Thread Confinement‣Single NSMangedObjectContext per thread‣Manual notifications, merging, and saving‣Fairly easy to understand, but harder to manage
![Page 24: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/24.jpg)
Traditional Multi-Context
![Page 25: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/25.jpg)
Traditional Multi-Context- (void)loadData{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Create temp context NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init]; [context setPersistentStoreCoordinator:[(AppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator]]; // // Do lots of async work here // // Save the context. error = nil; if (![context save:&error]) { // Replace this implementation with code to handle the error appropriately. abort(); } });}
// Register for save notification in ViewDidLoad[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:context];
![Page 26: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/26.jpg)
Traditional Multi-Context- (void)loadData{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Create temp context NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init]; [context setPersistentStoreCoordinator:[(AppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator]]; // // Do lots of async work here // // Save the context. error = nil; if (![context save:&error]) { // Replace this implementation with code to handle the error appropriately. abort(); } });}
// Register for save notification in ViewDidLoad[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:context];
![Page 27: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/27.jpg)
Traditional Multi-Context- (void)loadData{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Create temp context NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init]; [context setPersistentStoreCoordinator:[(AppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator]]; // // Do lots of async work here // // Save the context. error = nil; if (![context save:&error]) { // Replace this implementation with code to handle the error appropriately. abort(); } });}
// Register for save notification in ViewDidLoad[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:context];
![Page 28: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/28.jpg)
Traditional Multi-Context- (void)contextDidSave:(NSNotification *)notification { dispatch_async(dispatch_get_main_queue(), ^{ NSManagedObjectContext *mainContext = [self.fetchedResultsController managedObjectContext]; [mainContext mergeChangesFromContextDidSaveNotification:notification]; });}
// Or
- (void)contextDidSave:(NSNotification *)notification { [self.managedObjectContext performSelectorOnMainThread: @selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:NO];}
![Page 29: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/29.jpg)
Traditional Multi-Context- (void)contextDidSave:(NSNotification *)notification { dispatch_async(dispatch_get_main_queue(), ^{ NSManagedObjectContext *mainContext = [self.fetchedResultsController managedObjectContext]; [mainContext mergeChangesFromContextDidSaveNotification:notification]; });}
// Or
- (void)contextDidSave:(NSNotification *)notification { [self.managedObjectContext performSelectorOnMainThread: @selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:NO];}
![Page 30: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/30.jpg)
Traditional Multi-Context
Code Examplehttps://github.com/mmorey/CoreDataMultiContext/tree/notification-context
![Page 31: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/31.jpg)
Parent Child Context
≥ iOS 5: Parent Child Contexts‣Grand Central Dispatch private dispatch queues‣Threading managed for you, no manual synchronization required‣Less complicated and more flexible than pre-iOS 5 method ‣Context can and should be nested
![Page 32: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/32.jpg)
Concurrency Types
‣NSConfinementConcurrencyType‣Separate contexts for each thread‣Default, Legacy option
‣NSPrivateQueueConcurrencyType‣MOC maintains private serialized queue‣Can be created from any other thread‣Idle queues are more efficient than extra threads
‣NSMainQueueConcurrencyType‣Similar to private queue but on the main queue
NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
![Page 33: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/33.jpg)
Parent Child Context
![Page 34: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/34.jpg)
Parent Child Context
PSC PSC
![Page 35: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/35.jpg)
Parent Child Context__block NSManagedObjectContext *managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];temporaryContext.parentContext = managedObjectContext; [temporaryContext performBlock:^{
// // Do lots of async work here // // Save the context. NSError *error = nil; if (![temporaryContext save:&error]) {abort();} [managedObjectContext performBlock:^{ // Save the context. NSError *error = nil; if (![managedObjectContext save:&error]) {abort();}
}]; // main}]; // temp context
![Page 36: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/36.jpg)
Parent Child Context__block NSManagedObjectContext *managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];temporaryContext.parentContext = managedObjectContext; [temporaryContext performBlock:^{
// // Do lots of async work here // // Save the context. NSError *error = nil; if (![temporaryContext save:&error]) {abort();} [managedObjectContext performBlock:^{ // Save the context. NSError *error = nil; if (![managedObjectContext save:&error]) {abort();}
}]; // main}]; // temp context
![Page 37: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/37.jpg)
Parent Child Context__block NSManagedObjectContext *managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];temporaryContext.parentContext = managedObjectContext; [temporaryContext performBlock:^{
// // Do lots of async work here // // Save the context. NSError *error = nil; if (![temporaryContext save:&error]) {abort();} [managedObjectContext performBlock:^{ // Save the context. NSError *error = nil; if (![managedObjectContext save:&error]) {abort();}
}]; // main}]; // temp context
Private Queue save propagates up to parent
![Page 38: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/38.jpg)
Parent Child Context__block NSManagedObjectContext *managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];temporaryContext.parentContext = managedObjectContext; [temporaryContext performBlock:^{
// // Do lots of async work here // // Save the context. NSError *error = nil; if (![temporaryContext save:&error]) {abort();} [managedObjectContext performBlock:^{ // Save the context. NSError *error = nil; if (![managedObjectContext save:&error]) {abort();}
}]; // main}]; // temp context
Save to disc still locks PS which will block the UI during
read operations
![Page 39: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/39.jpg)
Basics
AppAppAppAppAppApp
NSManagedObjectNSManagedObjectNSManagedObjectNSManagedObjectNSManagedObjectNSManagedObject
NSManagedObjectContextNSManagedObjectContextNSManagedObjectContextNSManagedObjectContextNSManagedObjectContextNSManagedObjectContext
NSPersistentStoreCoordinatorNSPersistentStoreCoordinatorNSPersistentStoreCoordinator NSManagedObjectModelNSManagedObjectModelNSManagedObjectModel
NSPersistentStoreNSPersistentStoreNSPersistentStoreNSPersistentStoreNSPersistentStoreNSPersistentStore
SQLite XML BinaryBinary In Memory Custom
![Page 40: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/40.jpg)
Async Saving - Parent Child Context
![Page 41: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/41.jpg)
Async Saving - Parent Child Context// Child context- (NSManagedObjectContext *)managedObjectContext{ if (_managedObjectContext != nil) { return _managedObjectContext; } _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; _managedObjectContext.parentContext = [self writerManagedObjectContext]; return _managedObjectContext;}
// Parent context- (NSManagedObjectContext *)writerManagedObjectContext{ if (_writerManagedObjectContext != nil) { return _writerManagedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { _writerManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateQueueConcurrencyType]; [_writerManagedObjectContext setPersistentStoreCoordinator:coordinator]; } return _writerManagedObjectContext;}
![Page 42: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/42.jpg)
Async Saving - Parent Child Context// Child context- (NSManagedObjectContext *)managedObjectContext{ if (_managedObjectContext != nil) { return _managedObjectContext; } _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; _managedObjectContext.parentContext = [self writerManagedObjectContext]; return _managedObjectContext;}
// Parent context- (NSManagedObjectContext *)writerManagedObjectContext{ if (_writerManagedObjectContext != nil) { return _writerManagedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { _writerManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateQueueConcurrencyType]; [_writerManagedObjectContext setPersistentStoreCoordinator:coordinator]; } return _writerManagedObjectContext;}
![Page 43: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/43.jpg)
Async Saving - Parent Child Context// Child context- (NSManagedObjectContext *)managedObjectContext{ if (_managedObjectContext != nil) { return _managedObjectContext; } _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; _managedObjectContext.parentContext = [self writerManagedObjectContext]; return _managedObjectContext;}
// Parent context- (NSManagedObjectContext *)writerManagedObjectContext{ if (_writerManagedObjectContext != nil) { return _writerManagedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { _writerManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateQueueConcurrencyType]; [_writerManagedObjectContext setPersistentStoreCoordinator:coordinator]; } return _writerManagedObjectContext;}
![Page 44: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/44.jpg)
Parent Child Context__block NSManagedObjectContext *writerObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] writerManagedObjectContext];__block NSManagedObjectContext *managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];__block NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];temporaryContext.parentContext = managedObjectContext; [temporaryContext performBlock:^{ // // Do lots of async work here // [temporaryContext save:&error]; {abort();} // Save the context. [managedObjectContext performBlock:^{ [managedObjectContext save:&error]; {abort();} // Save the context.
[writerObjectContext performBlock:^{ [writerObjectContext save:&error]; {abort();} // Save the context. }]; // writer }]; // main}]; // temp context
![Page 45: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/45.jpg)
Parent Child Context__block NSManagedObjectContext *writerObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] writerManagedObjectContext];__block NSManagedObjectContext *managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];__block NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];temporaryContext.parentContext = managedObjectContext; [temporaryContext performBlock:^{ // // Do lots of async work here // [temporaryContext save:&error]; {abort();} // Save the context. [managedObjectContext performBlock:^{ [managedObjectContext save:&error]; {abort();} // Save the context.
[writerObjectContext performBlock:^{ [writerObjectContext save:&error]; {abort();} // Save the context. }]; // writer }]; // main}]; // temp context
NSMainQueueConcurrency
NSPrivateQueueConcurrencyType
![Page 46: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/46.jpg)
Asynchronous Saving - Parent Child Context
Code Examplehttps://github.com/mmorey/CoreDataMultiContext/tree/parent-context
![Page 47: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/47.jpg)
Still Blocking?
![Page 48: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/48.jpg)
Still Blocking?
Small and frequent saves during import
![Page 49: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/49.jpg)
Still Blocking?
Wait for opportunity when user won’t notice
![Page 50: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/50.jpg)
Still Blocking?
- (void)setStalenessInterval:(NSTimeInterval)expiration
![Page 51: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/51.jpg)
Still Blocking?
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"sections" cacheName:@"default-cache"];
![Page 52: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/52.jpg)
Still Blocking?
For VERY LARGE amounts of data it may be better to generate the SQLite file on the
server, download it asynchronously, and set it up as an additional persistent store.
![Page 53: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/53.jpg)
References
Nested MOC Release Notes: http://developer.apple.com/library/mac/#releasenotes/DataManagement/RN-CoreData/index.html
Core Data Programming Guide: http://developer.apple.com/library/mac/#documentation/cocoa/Conceptual/CoreData/cdProgrammingGuide.html
Cocoanetics Blog:http://www.cocoanetics.com/2012/07/multi-context-coredata/
http://www.cocoanetics.com/2013/02/zarra-on-locking/
![Page 54: Core Data with multiple managed object contexts](https://reader033.vdocuments.us/reader033/viewer/2022052823/55519838b4c905013a8b4a0d/html5/thumbnails/54.jpg)
Thanks!
Questions? Get in Touch.Twitter: @xzolianApp.net: @morey
Email: [email protected]: http://matthewmorey.com