をUIManagedDocument
使用してリストに表示するデータがありますNSFetchedResultsController
。データはバックグラウンドで定期的に更新され、変更はUIManagedDocument.managedObjectContext
(performBlock: を使用して) に配置されます。
ドキュメントのメイン コンテキストからデータを表示すると、すべてが期待どおりに機能します。しかし、メイン コンテキスト ( 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'
これは、新しいオブジェクトがドキュメント コンタクトに挿入された後にのみ発生します。自動保存が行われるまでしばらく待つと、リストが正常に表示されます。また、問題は、子コンテキストのみでsectionNameKeyPath
セットを持っている場合のみです。NSFetchedResultsController
これは、フェッチされた結果コントローラーをセットアップする方法です。派手なことは何もないので、ここで何が間違っているのかわかりません。
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 が互いにどのように関係しているかを説明しようと思います。
3 つの管理対象オブジェクト コンテキストが使用されます。
1)UIManagedDocument.managedObjectContext
ドキュメントを読み込んで作成されます。
2) 時々オブジェクトを更新するバックグラウンド スレッドが実行されています。これはドキュメント MOC を親とするプライベート キュー moc です。
context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
context.parentContext = repository.managedObjectContext;
[context performBlock:^{ /* updates */ }];
[context performBlock:^{ [context save:NULL]; }];
3) ユーザーが変更を加えたい場合、新しい MOC がドキュメント MOC の子として作成されます。これはメイン キューの MOC です。これは、上記のフェッチを実行するために使用されるコンテキストです。
バックグラウンド更新は NSOperationQueue から行われますが、バックグラウンド MOC へのすべてのアクセスは . で適切に囲まれてい-performBlock:
ます。他のすべてのアクセスは、メイン スレッドから行われます。
編集 3 : いくつかの設定で遊んでいるNSFetchRequest
ときに、設定すると問題が解決することがわかりましたfetchRequest.includesPendingChanges = NO
。しかし、UIManagedDocument によって変更がバックグラウンドで保存されるまで、ユーザーには更新が表示されないため、これは実行可能なソリューションではありません。