私はマルチスレッドを使用してデータを取得し、解析し、オブジェクトを作成して保存しています。そして、これがすべて完了した後、ウィンドウを表示したいと思います。しかし今、私には2つの問題があります。
- デッドロックがあります
- 私のバリアはバリアとして機能しません。
デッドロックは、一度に複数のスレッドでmanagedObjectContextを更新しているためだと思います。
そこで、ManagedObjectContextをConcurrencyTypeで変更しました。
__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
そして、並行性キューのimportContextを作成し、parentContextを割り当てました。
NSManagedObjectContext *importContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; importContext.parentContext = self.managedObjectContext;
そして、importContextのperformBlockに操作を配置します。
[importContext performBlock:^{ dispatch_async(backgroundQueue, ^{ [myObject methodAWithContext:importContext]; }); dispatch_async(backgroundQueue, ^{ [myObject methodBWithContext:importContext]; }); dispatch_async(backgroundQueue, ^{ [myObject methodCWithContext:importContext]; }); dispatch_barrier_async(backgroundQueueM, ^{ // create barrier to wait for the first 3 threads to be completed. dispatch_async(dispatch_get_main_queue(), ^{ // Save the data from the importContext tot the main context on the main queue NSError *importError = nil; [importContext save:&importError]; [importContext.parentContext performBlock:^{ NSError *parentError = nil; [importContext.parentContext save:&parentError]; }]; [self.window makeKeyAndVisible]; }); }); }];
アプローチ1:各メソッドで、オブジェクトのサブセットを選択し、これらを削除してから、新しいオブジェクトを作成して保存します。(削除は、フェッチを実行して、作成されるすべてのオブジェクトの存在を確認するよりも速いと思いました)。したがって、メソッドAIで、すべてのAObjectを選択し、それらを削除して、新しいAObjectを作成します。メソッドBIで、すべてのBObjectを選択し、それらを削除して、新しいBObjectを作成します。メソッドCIで、すべてのCObjectを選択し、それらを削除して、新しいCObjectを作成します。
しかし、「NSManagedObjectContextは他のコンテキストのオブジェクトを削除できません」というエラーが表示されます。
したがって、アプローチ2:削除を削除しました。しかし今、私はさまざまな異なるエラーを受け取ります.....そしてバリアは他のスレッドが実行されるのを待ちません。
Q1:何が間違っているのですか?
Q2:3つのスレッドが完了するのを待つためのバリアを取得するにはどうすればよいですか?
Q3:さまざまなスレッドのオブジェクトを削除/パージするにはどうすればよいですか?
(Appleのリリースノートとドキュメントを読みましたが、マルチスレッドとmanagedContextの組み合わせに関する明確な説明が見つかりません。)