Skip to content
Create a gist now

Instantly share code, notes, and snippets.

Multi-threaded Core Data import example
@interface DDImportOperation
@property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#import "DDImportOperation.h"
@implementation DDImportOperation
@synthesize managedObjectContext=managedObjectContext_,
- (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:
@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
[dataQueue addOperation:importOperation];
-(void)mergeChangesFromImport:(NSNotification*)notification {
SEL selector = @selector(mergeChangesFromContextDidSaveNotification:);
[self.managedObjectContext performSelectorOnMainThread:selector
// 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]];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.