Skip to content

Instantly share code, notes, and snippets.

@romainbriche
Created July 19, 2012 12:35
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save romainbriche/3143548 to your computer and use it in GitHub Desktop.
Save romainbriche/3143548 to your computer and use it in GitHub Desktop.
Thread-safe NSManagedObjectContext factory.
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface AZModel : NSObject
+ (AZModel *)sharedModel;
- (__strong NSManagedObjectContext *)managedObjectContextForCurrentThread;
- (__autoreleasing NSManagedObjectContext *)newManagedObjectContextForCurrentThread;
@end
#import "AZModel.h"
#import <objc/runtime.h>
@implementation AZModel
#define kAZModelModelName @"DataModel"
+ (AZModel *)sharedModel
{
static AZModel *instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[AZModel alloc] init];
});
return instance;
}
#pragma mark - Managed object context
- (__strong NSManagedObjectContext *)managedObjectContextForCurrentThread
{
static char key;
// That is the object we will use to associate managedObjectContext with
NSThread *currentThread = [NSThread currentThread];
// If there was one created before, return it
NSManagedObjectContext *moc = objc_getAssociatedObject(currentThread, &key);
if (moc) {
return moc;
}
// Otherwise create a new one and configure it
moc = [[NSManagedObjectContext alloc] init];
moc.persistentStoreCoordinator = [self persistentStoreCoordinator];
// Configure your moc here, for example:
moc.undoManager = nil;
moc.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
// Associate it with current thread, so it will be deallocated as soon as thread deallocated
objc_setAssociatedObject(currentThread, &key, moc, OBJC_ASSOCIATION_RETAIN);
return moc;
}
- (__autoreleasing NSManagedObjectContext *)newManagedObjectContextForCurrentThread
{
__autoreleasing NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
moc.persistentStoreCoordinator = [self persistentStoreCoordinator];
moc.undoManager = nil;
moc.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
return moc;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
static NSPersistentStoreCoordinator *PersistentStoreCoordinator;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURL *url = [[NSBundle mainBundle] URLForResource:kAZModelModelName withExtension:@"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:url];
NSString *storeURLString = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
storeURLString = [storeURLString stringByAppendingPathComponent:kAZModelModelName];
storeURLString = [storeURLString stringByAppendingPathExtension:@"sqlite"];
NSURL *storeURL = [NSURL fileURLWithPath:storeURLString];
NSError *error = nil;
PersistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
mom = nil;
NSDictionary *options = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
NSPersistentStore *persistentStore = [PersistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:options
error:&error];
if (!persistentStore) {
persistentStore = [PersistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:options
error:&error];
}
ZAssert(persistentStore != nil, @"Error initializing PSC: %@\n%@", [error localizedDescription], [error userInfo]);
});
return PersistentStoreCoordinator;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment