CoreDataとMultiThreadのメモ書き(不完全)
いまいち分かってないけどメモ書き
*2010/12/14 追加、基本ルールにすこし追記
*2010/12/17 追加、ごにょごにょと。
Stackoverflowに書いている事ではこんな感じ。
基本ルール
- NSPersistentStoreCoordinator は唯一にすること
- 同様に、NSManagedObjectModelも唯一になりますよっと。
- NSManagedObjectContext はスレッドごと
- 絶対に、他のスレッドにNSManagedObjectを渡さない
- 渡す場合は、objectIDを渡してそれを元に取得
- ただし注意が必要で、保存していない時、objectIDを渡してもtempIDなので意味がありませんですよっと。
- 保存したらmainthreadのNSManagedObjectContext に mergeChangesFromContextDidSaveNotification: を投げて。
- 渡す場合は、objectIDを渡してそれを元に取得
上だと、例えばネットから落としてきてDBに放りこむ処理をスレッドにやっても、メインスレッドには反映されないので、表示上は何も無しになるという頭の痛い事になります。ですので、Using Core Data on Multiple Threads | Duck Rowingでは、NSManagedObjectContextDidSaveNotification: が飛んできたらメインスレッドにある NSManagedObjectContext に mergeChangesFromContextDidSaveNotification: を投げています。
Using Core Data on Multiple Threads | Duck Rowing の例文
- (void)main { ... // Create context on background thread ApplicationController *appController = [[NSApplication sharedApplication] delegate]; NSManagedObjectContext *ctx = [[NSManagedObjectContext alloc] init]; [ctx setUndoManager:nil]; [ctx setPersistentStoreCoordinator: [appController persistentStoreCoordinator]]; // Register context with the notification center NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(mergeChanges:) name:NSManagedObjectContextDidSaveNotification object:ctx]; ... } - (void)mergeChanges:(NSNotification *)notification { ApplicationController *appController = [[NSApplication sharedApplication] delegate]; NSManagedObjectContext *mainContext = [appController managedObjectContext]; // Merge changes into the main context on the main thread [mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:YES]; }
不思議なことにこれをすると、insertしたオブジェクトも反映されます。
メインスレッドにも、 NSManagedObjectContextDidSaveNotification: を登録したらいいんじゃないのかという疑問もありますが、うまくいかなくて、意図的に投げてやらないと期待通りに動いてくれませんでした。
参考:
- ios - Core Data multi thread application - Stack Overflow
- Core Data Programming Guide の 「Concurrency with Core Data」の「Use Thread Confinement to Support Concurrency」
- Using Core Data on Multiple Threads | Duck Rowing