Skip to content

Instantly share code, notes, and snippets.

@ddemaree
Created July 7, 2012 14:46
Show Gist options
  • Save ddemaree/3066745 to your computer and use it in GitHub Desktop.
Save ddemaree/3066745 to your computer and use it in GitHub Desktop.
Multi-threaded Core Data import example
@interface DDImportOperation
@property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
-(void)initWithPersistentStoreCoordinator:(NSPersistentStoreCoordinator*)persistentStoreCoordinator;
-(void)saveChanges;
@end
#import "DDImportOperation.h"
@implementation DDImportOperation
@synthesize managedObjectContext=managedObjectContext_,
persistentStoreCoordinator=persistentStoreCoordinator_;
- (void)initWithPersistentStoreCoordinator:(NSPersistentStoreCoordinator*)persistentStoreCoordinator {
if (self = [super init]) {
self.persistentStoreCoordinator = persistentStoreCoordinator;
}
return self;
}
- (NSManagedObjectContext*)managedObjectContext {
if (!managedObjectContext_) {
managedObjectContext_ = [NSManagedObjectContext new];
managedObjectContext_.persistentStoreCoordinator = self.persistentStoreCoordinator;
}
return managedObjectContext_;
}
- (void)main {
// Do work, then
[self saveChanges];
}
- (void)saveChanges {
if ([[self threadedContext] hasChanges]) {
NSError *error;
BOOL contextDidSave = [[self threadedContext] save:&error];
if (!contextDidSave) {
// TODO: Handle error in a nicer way than:
abort()
}
}
}
@end
@implementation DDItemListViewController
// This object has pointers to a persistent store coordinator (self.psc) and
// MOC (self.managedObjectContext). For the sake of example, let's say this
// controller presents a UITableView backed by an NSFetchedResultsController,
// which in turn gets its data from self.managedObjectContext.
// In theory, when changes are merged into this controller's MOC the UI
// should be updated
// This is just for purposes of illustration; in the real app, imports/syncs
// could also be triggered by a timer, or on app launch, or whenever a local
// object is saved
-(IBAction)startImport {
NSOperationQueue *dataQueue = [[[UIApplication sharedApplication] delegate] dataQueue];
DDImportOperation *importOperation = [[DDImportOperation alloc] initWithPersistentStoreCoordinator:self.psc];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(mergeChangesFromImport:)
name:NSManagedObjectContextDidSaveNotification
object:importOperation.managedObjectContext];
[dataQueue addOperation:importOperation];
}
-(void)mergeChangesFromImport:(NSNotification*)notification {
SEL selector = @selector(mergeChangesFromContextDidSaveNotification:);
[self.managedObjectContext performSelectorOnMainThread:selector
withObject:notification
waitUntilDone:YES];
// TODO: Need to remove myself as an observer on importOperation's managed object context
// but also need to retain a reference to it somewhere?
// [[NSNotificationCenter defaultCenter] removeObserver:self
// name:NSManagedObjectContextDidSaveNotification
// object:[self threadedContext]];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment