2日後、CoreDataを複数のスレッドで動作させようとしています。NSOperationsで標準のスレッド制限メソッドを試し、通知をマージし、objectWithIdを使用して、スレッドごとのコンテキストのディクショナリを試しましたが、それでも奇妙なデッドロック、不整合の例外、その他の厄介なものがたくさんあります。それは私を夢中にさせています...さらに、両方のスレッドが共有永続ストアに変更を加える可能性がある場合に、2つのスレッドでコンテキストを管理する方法についての単一の例や説明を見つけることができません...
新しいiOS5の方法を使おうとしましたが、それでもエラーが発生します。最初の問題は、コンテキストを保存するときのデッドロックです。私はすべての不要なコードを削除し、このコードを十分に速く実行するとデッドロックが発生します(ボタンをすばやくタップすることによって):
NSManagedObjectContext *context = [StoreDataRetriever sharedRetriever].managedObjectContext;
for (int i = 0; i < 5; i++) {
NSError *error = nil;
NSLog(@"Main thread: %@, is main? %d", [NSThread currentThread], [NSThread isMainThread]);
BOOL saveOK = [context save:&error];
if (!saveOK) {
NSLog(@"ERROR!!! SAVING CONTEXT IN MAIN");
}
[context performBlock:^{
NSLog(@"Block thread: %@", [NSThread currentThread]);
NSError *error = nil;
BOOL savedOK = NO;
savedOK = [context save:&error];
if (!savedOK) {
NSLog(@"ERROR!!! SAVING CONTEXT IN BLOCK");
}
}];
}
データベースに他の変更はなく、コンテキストを保存するだけです。このコードの何が問題になっていますか?それはどのように見えるべきですか?
注:[StoreDataRetriever sharedRetriever] .managedObjectContextは、initWithConcurrencyType:NSPrivateQueueConcurrencyTypeを使用してappDelegateで作成されます。