7

To-Manyリレーションシップで何が発生するか、親エンティティからのリレーションのウォークに依存するタイミング、および新しいフェッチリクエストを作成するタイミングに関連する、CoreDataの動作に関するいくつかの「理論」の質問があります。それらはすべて非常に関連しています。

バックグラウンド

RPBookと多対関係にある親エンティティを想定しRPChapterます。本には多くの章があります。コアデータモデルでもその逆が設定されています。手動で順序付けられた関係の基本的な形式が含まれるため、RPChapterエンティティにはchapterIndexプロパティがあります。私はここでiOS5の新しい順序付けられた関係を使用していません(これらの質問にもそれほど関連していません)。

本の章にたどり着くには、chaptersリレーションシップアクセサーを使用します。

RPBook *myBook; // Assume this is already set to an existing RPBook
NSSet *myChapters = myBook.chapters

使用法/セットアップ

iPhoneアプリでは、RPBookインスタンスのリストを表示するテーブルビューから始めます。対応するチャプターまだ必要ないため、テーブルビューをサポートするフェッチされた結果コントローラーのフェッチ仕様の一部としてプリフェッチされません。

これらのインスタンスの1つを選択するRPBookと、新しいページが表示され、ビューコントローラにこのインスタンス参照があります。これにはプリフェッチRPBookされていません。chapters

質問1:すぐfilteredSetUsingPredicate:に関係を呼び出すchapters

chapters直接を使用してリレーションを介してフィルタリングしたい場合、私が見ている現在の関連するすべてのインスタンスをfilteredSetUsingPredicate:プリフェッチしなかった場合、それは確実に機能しますか?言い換えれば、その関係にあるすべてのオブジェクトの舞台裏で障害を引き起こして、そのことを実行するのでしょうか、それとも、誤解を招くように、すでにメモリにあるチャプター(存在する場合)に基づいた結果しか得られないのでしょうか?RPChapterRPBookfilteredSetUsingPredicate:

本に関連する章の数が非常に少ない場合は、代わりにallObjects最初に呼び出してスタイルを設定する必要がありますか?すなわち

[[self.chapters allObjects] filteredArrayUsingPredicate:predicate]

ただの代わりに:

[self.chapters filteredSetUsingPredicate:predicate]

質問2:すべての本の章のバッチ検索

RPBookインスタンスはあるが、それに関連するプリフェッチされたインスタンスがない場合、リレーションRPChapterを使用して本のすべてのチャプターを一度にフェッチするようにするにはどうすればよいchaptersですか?それを行うのですか[myBook.chapters allObjects]、それともその呼び出しから障害を取り戻すことができますか?

上記の質問1のように、コアデータが、リレーションRPChapterでの使用の動作に影響を与えるかどうかを尋ねられた奇数のフォールトをトリップするのではなく、バッチですべてのフォールトを実行するようにします。filteredSetUsingPredicate:chapters

これを行うには、明示的なフェッチ要求に頼る必要がありますか?すでに持っているものを再フェッチする必要がRPBookありますが、今回はフェッチリクエストで、関連するすべてのチャプターも使用してフェッチするようにリクエストしますsetRelationshipKeyPathsForPrefetching:か?

この最後のオプションは私には無駄に思えます。b/c私はすでに、RPChapter関心のあるすべてのインスタンスのサブセットを概念的に表すスコープ関係を持っています。可能な限り、オブジェクトグラフを歩きたいだけです。

質問3:同じスレッド上のRPChapterインスタンスのNSFetchedResultsController

セットアップ この場合、RPBookインスタンスはありますが、それに関連するプリフェッチされたRPChapterインスタンスはありません(ただし、ストアには存在します)。同じViewControllerで、まったく同じ本にスコープされたインスタンスもありNSFetchedResultsController (FRC)ます。RPChapterつまり、同じスレッド、同じ管理対象オブジェクトコンテキストです。

FRCのインスタンスはRPChapter、メモリ内で、同じオブジェクトを共有する、RPChapter取得したインスタンスの対応物と同じオブジェクトになりますか?言い換えると、ランタイムは、メモリ内の異なる物理オブジェクトを使用して、同じスレッド内の同じMOCからの同じものに対する管理対象オブジェクトの要求を実行しますか?myBook.chaptersObjectIDObjectID

NSFetchedResultsController質問4:リレーションのクエリを提供するために管理対象オブジェクト内にインストールするデザインパターン

chaptersカスタムRPChapter管理対象オブジェクトサブクラスで提供される組み込みの関係を使用して、内容が頻繁に変更される関係(私の例では本の章)に関するクエリを処理できるかどうかを判断しようとしています。設計/アーキテクチャの観点から、インスタンスのを管理対象オブジェクトクラスにインストールしFRCRPChapterそのRPBook本の章に関するクエリを効率的に処理します。

chaptersたとえばアクセサーだけに頼ることができれば明らかにクリーンですがmyBook、to-many関係に大量の宛先エンティティが存在する状況では、ここでのFRCの方が実際にはパフォーマンスと効率が高いようです。

これはやり過ぎですか、それともさまざまな方法でその章についてFRCクエリを実行するためのフェアユースですか?RPBookどういうわけか、オブジェクトグラフを単純に歩く機会を逃しているように感じます。インスタンスをロードするときに、リレーションが常に最新であると信頼できるようにしたいと思います。chaptersRPBook

4

1 に答える 1

10

質問1

はい、動作します。呼び出すと[book chapters]、セットが自動的に入力されます。これらのオブジェクトをフィルタリングすると、エラーが発生します。

NSFetchedResultsControllerただし、配列を取得する代わりに、述語が@ "book ==%@"のようなものであるhereを使用する必要があります。

質問2

NSManagedObjectContextにすべてのチャプターをロードするように強制する最良の方法は、を実行し、障害ではなく完全に実現されたオブジェクトを返すNSFetchRequestように構成することです。NSFetchRequestこれにより、それらすべてが一度にプリロードされます。ただし、大量のチャプターがない限り、ここで多くの節約を得ることができません。

なんで?

これらのチャプターをリクエストすると、障害が発生した状態でも、Core Dataがデータをキャッシュにロードするため(バイナリデータなどのいくつかのエッジケースを除く)、オブジェクトを「障害」が発生すると、ポインターが移動するだけになります。メモリと追加のディスクヒットはありません。

プリフェッチのメリットを確認するには、おそらく何千ものチャプターが必要になります。

質問3

はい。それらは同じオブジェクトになります。 NSManagedObject同じから取得した場合、インスタンスは常に共有されますNSManagedObjectContext。それはの仕事の一部ですNSManagedObjectContext

質問4

あなたNSFetchedResultsControlerはその仕事であるを使いたいです。それらを手動で管理することは無駄であり、CoreDataの実装よりも効率が悪いことがほぼ保証されています。

ただし、別のスレッドから調整しない限り、関係常に最新になります。したがって、更新を期待しない場合は、配列を使用できます。私はしません。

于 2012-02-16T21:37:56.147 に答える