NSFRC fetchedObjects 配列が返すべきオブジェクトをすべて返さないという奇妙な問題に直面しています。コンテキストを説明するために、私のアプリケーションにはいくつかのリスト ビュー コントローラーがあり、それぞれに NSFRC があります。デリゲート メソッド controllerDidChangeContent 内のリスト ビューを更新しています。私が直面している問題は次のとおりです。オブジェクトをバックグラウンド MOC に保存して保存した後、controllerDidChangeContent が呼び出されますが、バックグラウンド スレッドに保存したばかりのオブジェクトが NSFRC に表示されません。これを確認するために使用しているコードは次のとおりです。
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
NSManagedObjectContext *context = controller.managedObjectContext;
NSError *error = nil;
NSArray *array = [context executeFetchRequest:controller.fetchRequest error:&error];
if (nil != array) {
NSUInteger count = MIN(controller.fetchedObjects.count, array.count);
for (NSUInteger index=0; index<count; index++) {
NSManagedObject *a = array[index];
NSManagedObject *b = controller.fetchedObjects[index];
// Here you will see that sometimes the objects don't match
NSLog(@"%d: %@ <--> %@", index, [[a body] text], [[b body] text]);
}
}
}
NSFRC fetchedObjects 配列が、手動の executeFetchRequest によって返される配列と同一であることを期待しています (データを手動で取得するために NSFRC fetchRequest を使用しています)。しかし、そうではありません。手動の executeFetchRequest は、NSFRC fetchedObjects よりも多くのオブジェクトを返します。誰が何が起こっているのか知っていますか?NSFRC のキャッシュをオフにしましたが、同じ動作が報告されています。
ありがとう!
===更新====
その問題に関するいくつかの更新。NSFRC から一貫性のない結果をいくつか見ることができ、さらに問題のオブジェクトに「触れる」ことを含む回避策によって問題を修正できたため、Core Data にバグがあると思います。何が起こっているかを説明するシナリオを次に示します。
次の Core Data モデルを想像してください。 - Cat オブジェクトと Master オブジェクトがあります。- 猫は 1 人以上のマスターを持つことができます。- マスターは 1 つまたは複数の猫を持つことができます。- 最初の NSFRC (NSFRC_A と呼びましょう) が作成され、"Master_A" という名前のマスターを持つすべての猫が取得されます。述語は { ANY master.name == "Master_A" } です。- 2 番目の NSFRC (NSFRC_B と呼びましょう) が作成され、「Master_B」という名前のマスターを持つすべての猫が取得されます。述語は { ANY master.name == "Master_B" } です。- UI スレッドでのみ使用されるメイン管理オブジェクト コンテキストがあります。 - メイン管理オブジェクト コンテキストと同じ永続ストアを使用して、バックグラウンド スレッドごとに作成されたバックグラウンド管理オブジェクト コンテキストがあります。
「Cat_A」という名前の猫がバックグラウンドで作成され、マスター「Master_A」に割り当てられます。バックグラウンド コンテキストが保存された後、メイン コンテキストが適切に更新されます。この時点で、NSFRC_A はデリゲートに変更が発生したことを通知し、「Cat_A」を正しく報告します。
その後、バックグラウンド スレッドで、同じ猫「Cat_A」にマスター「Master_B」が割り当てられます。バックグラウンド コンテキストが保存された後、メイン コンテキストが適切に更新されます。この時点で、NSFRC_A はデリゲートにその変更を通知し、「Cat_A」を正しく報告します。NSFRC_B もそのデリゲートにその変更を通知しますが、"Cat_A" を報告しません (その fetchedObjects から欠落しています)。ただし、NSFRC_B と同じ fetchRequest を使用して手動でフェッチを実行すると、"Cat_A" が返されていることがわかります。奇妙なことは、返される「Cat_A」インスタンスが障害としてマークされていることです。これは、NSFRC_B がメモリに表示されないために「Cat_A」を返さない理由を説明しています。
これはバグです。なぜなら、バックグラウンド スレッドからの変更がメイン コンテキストにマージされたときに、"Cat_A" 関係をマスターに記録するだけでその動作を修正できるからです。