GCD を介して、ユーザー定義の同時実行キューで同時にディスパッチされる 2 つのブロックがあります。ブロック フローのある時点で、同じセットのコア データ管理オブジェクトにアクセスする必要があります。フェッチによって明示的にではなく、対多リレーション セットを持つ既にフェッチされたオブジェクトを介して。
私が理解している限り、ブロックにはそれぞれ独自のコンテキストが必要であり、完了時に両方のコンテキストをメインスレッドのコンテキストにマージする必要があります。
ただし、2 つのコンテキストを作成してから 3 つ目のコンテキストにマージする代わりに、次のような方法があるかどうか疑問に思っています。
- (void)someMethodThatAppliesToAdisjointSetWithRange:(NSRange)range fromSharedObject:(NSManagedObject*)someSharedObject
{
// Do some stuff...
// Create sortDescriptors
__block NSArray* entities = nil;
dispatch_sync(dispatch_get_main_queue(), ^{
entities = [[[someSharedObject valueForKey:@"sprites"] sortedArrayUsingDescriptors:sortDescriptors] retain];
entities = [entities subarrayWithRange:range]
});
for(id anEntity in entities)
{
// STRICTLY retrieve properties from the entities
// And do stuff with these, BUT DON'T modify the entities themselves.
}
// Continue doing stuff that has nothing to do with the managed objects.
}
- (void)dispatchMethod
{
dispatch_async(_concurrentQueue, ^{
[self someMethodThatAppliesToAdisjointSetWithRange:NSMakeRange(0, floor(pageData.count/2.)) fromSharedObject:someSharedObject];
});
dispatch_async(_concurrentQueue, ^{
[self someMethodThatAppliesToAdisjointSetWithRange:NSMakeRange(floor(pageData.count/2.), ceil(pageData.count/2.)) fromSharedObject:someSharedObject];
});
}
上記についての私の考えは、メイン スレッドでのディスパッチが並行フロー内に同期ポイントを作成するということです。管理対象オブジェクト自体を変更することさえしていないので、問題ないはずです。ただし、テストの 1 日中のある時点で、コア データの「ステートメントはまだアクティブです」という不一致の例外が発生しました。だから今、彼は上記のコードはまだ安全ではないと考えています。ただし、例外は実際にはアプリ内の他のコードによって引き起こされた可能性があります。
何かご意見は?