In addition to the other respondents I provide the following advice...
Create two contexts during the construction of your core data stack and using:
- NSPrivateQueueConcurrencyType,
- NSMainQueueConcurrencyType.
Know that you'll need to hook up your NSPersistentStoreCoordinator
to the NSPrivateQueueConcurrencyType
.
and [UPDATE]
Make the MOC of NSPrivateQueueConcurrencyType
the parent of the NSMainQueueConcurrencyType
.
I've prepared my Core Data solutions based a lot on what I've learned from reading Marcus Zarra's book, from The Pragmatic Bookshelf – "Core Data, 2nd Edition, Data Storage and Management for iOS, OS X, and iCloud" (Jan 2013) in particular the chapters on (4) Performance Tuning and (5) Threading.
For a more up to date and all encompassing solution that I have not yet implemented, read this article My Core Data Stack by Zarra.
My solution involves writing a custom save method built alongside (in the same class as) my core data stack, shown following. Note that the save method is called at appropriate points in code.
Using this mechanism, constant and regular saves are persisted to memory (fast) in the main queue, and saves to the database are persisted to disk (slow) in a private queue.
Maybe this is a suitable path for you to consider - it works very well for me?
Properties...
@property (nonatomic, strong) NSManagedObjectContext *mocPrivate;
@property (nonatomic, strong) NSManagedObjectContext *mocMain;
Custom save method...
- (void)saveContextAndWait:(BOOL)wait {
if ([self.mocMain hasChanges]) {
[self.mocMain performBlockAndWait:^{
NSError __autoreleasing *error;
BOOL success;
if (!(success = [self.mocMain save:&error]))
NSLog(@"%@ - %@ - CORE DATA - E~R~R~O~R saving managedObjectContext MAIN: %@, %@", NSStringFromClass(self.class), NSStringFromSelector(_cmd), error.localizedDescription, error.localizedFailureReason);
NSLog(@"%@ - %@ - CORE DATA - Success saving managedObjectContext MAIN?: %@", NSStringFromClass(self.class), NSStringFromSelector(_cmd), success ? @"YES_" : @"NO_");
}];
}
void (^savePrivate) (void) = ^{
NSError __autoreleasing *error;
BOOL success;
if (!(success = [self.mocPrivate save:&error]))
NSLog(@"%@ - %@ - CORE DATA - E~R~R~O~R saving managedObjectContext PRIVATE: %@, %@", NSStringFromClass(self.class), NSStringFromSelector(_cmd), error.localizedDescription, error.localizedFailureReason);
NSLog(@"%@ - %@ - CORE DATA - Success saving managedObjectContext PRIVATE?: %@", NSStringFromClass(self.class), NSStringFromSelector(_cmd), success ? @"YES_" : @"NO_");
};
if ([self.mocPrivate hasChanges]) {
if (wait) {
[self.mocPrivate performBlockAndWait:savePrivate];
} else {
[self.mocPrivate performBlock:savePrivate];
}
}
}