UIManagedDocument
には、NSFetchedResultsController
を使用してリストに表示するデータがあります。データはバックグラウンドで定期的に更新され、変更はUIManagedDocument.managedObjectContext
に(performBlockを使用して)適用されます。子コンテキストでNSFetchedResultsControllerをフェッチできません
ドキュメントのメインコンテキストからデータを表示すると、すべて正常に動作します。しかし、すぐに、私はメインのコンテキスト(child.parentContext = document.managedObjectContext
)の子であるコンテキストでリストを表示するように、私は、任意のオブジェクトが表示されないと、次のエラーがコンソールに出力されます。
foo[17895:15203] CoreData: error: (NSFetchedResultsController)
The fetched object at index 5 has an out of order section name 'E.
Objects must be sorted by section name'
にのみ発生します新しいオブジェクトが文書の連絡先に挿入された後。自動保存が実行されるのを待つと、リストが正常に表示されます。また、問題は私がNSFetchedResultsController
に設定した子コンテキストでのみsectionNameKeyPath
が設定されている場合です。
これは私のセットアップフェッチ結果コントローラ、私は私が間違ってここに何ができるかを見ていないので、派手な何がどのようである:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Contact"];
fetchRequest.sortDescriptors = [Contact userDefinedSortDescriptors];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"hidden == nil || hidden == NO"];
NSFetchedResultsController *fetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:_managedObjectContext
sectionNameKeyPath:[Contact userDefinedSectionNameKeyPath]
cacheName:@"ContactList"];
[Contact userDefinedSortDescriptors]
と[Contact userDefinedSectionNameKeyPath]
実行時に解決されています。ソート記述子には、最初のエントリとしてsectionNameKeyPathが含まれています。どちらもnil
やその他の面白いものはありません。
:曖昧な部分を明確にしました。具体的には、ドキュメントの管理オブジェクトコンテキストで-save:を呼び出さない。
編集2:MOCが互いにどのように関係しているかを説明しようとします。
1)ドキュメントをロードすることによって作成されたUIManagedDocument.managedObjectContext
:
は、劇中の3つの管理対象オブジェクトコンテキストがあります。
2)オブジェクトを時折更新するバックグラウンドスレッドが実行されています。
context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
context.parentContext = repository.managedObjectContext;
[context performBlock:^{ /* updates */ }];
[context performBlock:^{ [context save:NULL]; }];
3)ユーザーが新しいMOCは、文書MOCの子として作成された変更を行いたい:これは親としての文書MOCとプライベートキューMOCです。これはメインキューMOCです。上記のフェッチを実行するために使用されるコンテキストです。
バックグラウンド更新はNSOperationQueueから実行されますが、バックグラウンドMOCへのすべてのアクセスは適切に-performBlock:
で囲まれています。他のすべてのアクセスはメインスレッドから行われます。
編集3:NSFetchRequest
にいくつかの設定で遊んでいる間、私はfetchRequest.includesPendingChanges = NO
を設定するときに問題が消えることがわかりました。しかし、これは実行可能な解決策ではありません。なぜなら、UIManagedDocumentによって変更がバックグラウンドで保存されるまで、ユーザは更新をもう見ないからです。
複数のコンテキストは扱いにくいです。したがって、あなたの_managedObjectContextはドキュメントのメインMOCの子ですか?どのコンテキストにオブジェクトを挿入していますか?また、setShouldRefreshRefetchedObjectsと、フェッチが実際にオブジェクトを取得する方法を決定するその他のフェッチプロパティを見てください。 –
_managedObjectContextは、メインMOCまたはメインMOCの子であり、コントローラのロード方法に応じて異なります。それが主なMOCであるときはすべて正常ですが、それが子供の場合は、私が説明した問題が発生します。他の子MOCにオブジェクトを挿入し、完了したらこの子を保存します。 – Alfonso
また、shouldRefreshRefetchedObjectsをYESに設定しようとしましたが、動作しませんでした。ほとんどの場合、変更はメインMOCに適用された後(メインMOCが保存される前)にフェッチが行われるため、影響はありません。 – Alfonso