iRSSの日記

はてなダイアリーiRSSの日記の続き

MagicalRecordメモ

https://github.com/magicalpanda/MagicalRecord/blob/develop/Docs/DefaultManagedObjectContext.md

MagicalRecordの初期化で↓をすると

[MagicalRecord setupAutoMigratingCoreDataStack];
+ (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator;
{
    if (defaultManagedObjectContext_ == nil)
    {
        NSManagedObjectContext *rootContext = [self MR_contextWithStoreCoordinator:coordinator];
        [self MR_setRootSavingContext:rootContext];
        
        NSManagedObjectContext *defaultContext = [self MR_newMainQueueContext];
        [self MR_setDefaultContext:defaultContext];
        
        [defaultContext setParentContext:rootContext];
    }
}

rootContextとして、

+ (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator;
{
	NSManagedObjectContext *context = nil;
    if (coordinator != nil)
	{
        context = [self MR_contextWithoutParent];
        [context performBlockAndWait:^{
            [context setPersistentStoreCoordinator:coordinator];
        }];
        
        MRLog(@"-> Created Context %@", [context MR_workingName]);
    }
    return context;
}

+ (NSManagedObjectContext *) MR_contextWithoutParent;
{
    NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    return context;
}

で、NSPrivateQueueConcurrencyTypeのcontextをつくる

rootSavingContext
として、
static NSManagedObjectContext *rootSavingContext = nil;
で保持

defaultContextMR_newMainQueueContext
はNSMainQueueConcurrencyTypeなので、メインスレッドでつかうのはこっち
fetchedResultsControllerをTableView用につくるなら [NSManagedObjectContext MR_defaultContext]をcontextとしてつかう。

基本はこの2個

+ (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;
	}
}

MR_contextForCurrentThreadは、MainThreadならMR_defaultContextを返し、別スレッドにいるときは、そのスレッド内で有効なContextをMR_defaultContextのchild contentとして、返してくれる。

なのでMR_contextForCurrentThread使っていれば、まあ、大丈夫。

threadContextでsaveしたとき、contextがネストしていても親をたどって、保存してくれる。
threadContextの親はMR_defaultContextなので MR_newMainQueueContext NSMainQueueConcurrencyTypeのcontextに伝達されるので、それにつながっているfetchedResultsControllerにも伝わる。

save時
MR_defaultContextを使っているなら、MR_defaultContextでsaveしないで、MR_rootSavingContextで保存するrootSavingContextには、親contextがいない?

https://github.com/magicalpanda/MagicalRecord/blob/develop/Docs/Threads.md
どのthreadContextで保存しても、伝わるから大丈夫