How to instantiate an NSManagedObjectContext in iOS 9

Prior to iOS 9, Apple would do the heavy lifting and setup a Core Data stack with certain templates. One of those methods was the custom initialiser for the managed object context in the AppDelegate.m file.

Since iOS 9 however, the standard init method is deprecated and we need to use a designated initialiser instead, called initWithConcurrency. This initialiser has been around since iOS 5, but up until now it was optional to use it.

Here’s what a typical custom initialiser for a managed object context looked like prior to iOS 9:

- (NSManagedObjectContext *)managedObjectContext {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    }
    _managedObjectContext = [[NSManagedObjectContext alloc] init];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;
}

Opening a project with a method like this now will give us a deprecation warning and we must use initWithConcurrency instead.

This means that we now have to make a choice about what thread our managed object context is initialised on: the main queue, or perhaps a special background queue we’ve created. Our choices are:

  • NSPrivateQueueConcurrencyType
  • NSMainQueueConcurrencyType

Unless you have a private queue, the previous default behaviour can be brought back with the latter option. Here’s what the updated method would look like:

- (NSManagedObjectContext *)managedObjectContext {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    }

    // since iOS 9
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;
}




Leave a Reply