コード書いてて色々よくわからなかったのでメモ。
デフォルトのpersistentStoreCoordinator
CoreData初期化時に特に指定がなければSQLiteストアを使用する。
+ (void) setupCoreDataStack
{
[self setupCoreDataStackWithStoreNamed:[self defaultStoreName]];
}
+ (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName
{
if ([NSPersistentStoreCoordinator MR_defaultStoreCoordinator] != nil) return;
NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithSqliteStoreNamed:storeName];
[NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];
[NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator];
}
デフォルトのSQLiteデータベースファイル名
作成されるファイルはアプリ名(kCFBundleNameKey
)+ .sqliteとなる。アプリ名がSampleApp
であればSampleApp.sqlite
というファイルになる。
+ (NSString *) defaultStoreName;
{
NSString *defaultName = [[[NSBundle mainBundle] infoDictionary] valueForKey:(id)kCFBundleNameKey];
if (defaultName == nil)
{
defaultName = kMagicalRecordDefaultStoreFileName;
}
if (![defaultName hasSuffix:@"sqlite"])
{
defaultName = [defaultName stringByAppendingPathExtension:@"sqlite"];
}
return defaultName;
}
デフォルトのNSManagementObjectContext
[NSManagedObjectContext MR_defaultContext]
で取得できるコンテキストは、アプリケーション起動後に最初にsetupしたpersistentStoreCoordinator(SQLiteストア)を利用したコンテキストが返される。
+ (NSManagedObjectContext *) MR_defaultContext
{
@synchronized (self)
{
NSAssert(defaultManagedObjectContext_ != nil, @"Default Context is nil! Did you forget to initialize the Core Data Stack?");
return defaultManagedObjectContext_;
}
}
iCloudストアを利用した場合はNSNotificationCenter
のオブザーバ設定が行われる。
+ (void) MR_setDefaultContext:(NSManagedObjectContext *)moc
{
if (defaultManagedObjectContext_)
{
[[NSNotificationCenter defaultCenter] removeObserver:defaultManagedObjectContext_];
}
NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_defaultStoreCoordinator];
if (iCloudSetupNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:iCloudSetupNotificationObserver];
iCloudSetupNotificationObserver = nil;
}
if ([MagicalRecord isICloudEnabled])
{
[defaultManagedObjectContext_ MR_stopObservingiCloudChangesInCoordinator:coordinator];
}
defaultManagedObjectContext_ = moc;
[defaultManagedObjectContext_ MR_setWorkingName:@"DEFAULT"];
// [moc MR_obtainPermanentIDsBeforeSaving];
if ([MagicalRecord isICloudEnabled])
{
[defaultManagedObjectContext_ MR_observeiCloudChangesInCoordinator:coordinator];
}
else
{
// If icloud is NOT enabled at the time of this method being called, listen for it to be setup later, and THEN set up observing cloud changes
iCloudSetupNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMagicalRecordPSCDidCompleteiCloudSetupNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
[[NSManagedObjectContext MR_defaultContext] MR_observeiCloudChangesInCoordinator:coordinator];
}];
}
MRLog(@"Set Default Context: %@", defaultManagedObjectContext_);
}
ローカルなコンテキスト
[NSManagedObjectContext MR_context]
を実行すると、parentContext
にデフォルトコンテキストが代入されたローカルなNSManagedObjectContext
オブジェクトを取得することが出来る。
+ (NSManagedObjectContext *) MR_context;
{
NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[context setParentContext:[self MR_defaultContext]];
return context;
}
スレッドコンテキスト
NSManagedObjectContext MR_contextForCurrentThread]
を使用するとスレッドローカルなNSManagedObjectContext
を取得することが出来る。上記のローカルなコンテキスト(この呼び方でいいのか?)とは、MR_contextForCurrentThread
を経由して取得すると、メインスレッドかそれ以外かを考慮したスレッドが返却される点が異なる。
メインスレッドから呼び出した場合はdefualtContext
が、それ以外は上記と同様ローカルなコンテキストが返る。
+ (NSManagedObjectContext *) MR_contextForCurrentThread;
{
if ([NSThread isMainThread])
{
return [self MR_defaultContext];
}
else
{
NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary];
NSManagedObjectContext *threadContext = [threadDict objectForKey:kMagicalRecordManagedObjectContextKey];
if (threadContext == nil)
{
threadContext = [self MR_contextWithParent:[NSManagedObjectContext MR_defaultContext]];
[threadDict setObject:threadContext forKey:kMagicalRecordManagedObjectContextKey];
}
return threadContext;
}
}