public
Created

Multi-threaded Core Data import example

  • Download Gist
DDImportOperation.h
Objective-C
1 2 3 4 5 6 7 8 9
@interface DDImportOperation
 
@property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
 
-(void)initWithPersistentStoreCoordinator:(NSPersistentStoreCoordinator*)persistentStoreCoordinator;
-(void)saveChanges;
 
@end
DDImportOperation.m
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
#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
DDItemListViewController.m
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
@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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.