2009-07-17 12 views
13

オブジェクトAと多対多の関係を持つオブジェクトB(つまりA - >> B)をフェッチしたいとします。私はすでに記憶にAを持っています。私はAからBオブジェクトのNSSetを取得することができますが、Bオブジェクトのフェッチ要求を行う方がよいでしょうか(特に、UITableViewの日付でセクションを並べ替える場合)コアデータ別のオブジェクトとの関係にあるオブジェクトを取得する

1つのオブジェクトAに属するB個のオブジェクトしか取得できないような要求をどうすればできますか?

答えて

5

あなたが求めていることをするためには、クラスBで逆の関係を指定する必要があります。

しかし、なぜオブジェクトAに既に入っているBオブジェクトのセットを取り込むのかはわかりません。オブジェクトAは既にレイジーに読み込まれていますが、あなたは既にメモリにAがあるので、私は新しいNSPredicateを指定して完全に新しいFetchを作成するよりも、単にAからセットを取得するほうが効率的であることを熟知しています(ただし、専門家は検証する必要があります)。

言うまでもなく、iPhoneよりも遅いデバイスでさえも、「効率的」とはミリ秒単位で話しています。私は構文がクリーナーなので、オブジェクトAからセットを取得したいと思います。それがより速いかもしれないという事実は、ボーナスです。

+1

Bオブジェクトを日付順に並べ替えたいので、私はこの質問をしました。そして、私は、コードを使用するのではなく、コアデータデータベースに大きなセット(潜在的に200+)のオブジェクトを用意する方が高速で、CPU集約的ではないかもしれません。 –

+0

Devin:Bオブジェクトをソートする場合は、元の質問にそのオブジェクトを追加する必要があります。私も答えを知りたいです! –

+0

私もこれに興味があります:http://stackoverflow.com/questions/4003659/is-it-possible-to-have-core-data-sort-the-many-part-of-a-to-many -relationship-d。あなたはバッチを強制的に強制することができます。もしあなたがそれをソートすることができるのだろうか? – JoBu1324

6

すでにAのインスタンスを保持している場合は、Aのアクセサを使用して関連するBインスタンスにアクセスしてください。

特定のAに関連するすべてのB(この場合はそうではありません)を直接フェッチする必要がある場合は、(逆の)関係に基づく述語を使用してBエンティティのフェッチ要求を作成します(具体的な構文は、逆関係名に依存し、その逆が1対多であるか多対多であるかによって異なります)。

2

私は同様の状況にあります。

NSFetchedResultsControllerを使用して、1対多(A→B)の関係でBを管理したいと考えています。さて、これを行うための一つの方法は、以下のような述語を構築し、エンティティBにそれを適用することです:

NSPredicate *Predicate = [NSPredicate predicateWithFormat: 
            @"ANY hasParent.label == 'A'"]; 

しかし、これは物事の恐ろしく遅い方法であり、すべてのコストで回避する必要があります。 私はこれを25,000個のオブジェクトで試して約300個を取り出し、シミュレータを約15秒かかった。 iPhoneでフェッチを完了せず、繰り返しクラッシュします。

もう1つの方法は、既に述べたことを行うことです。NSArrayをAが保持するセットから作成してソートします。 allObjectsをセットに送ると、配列が返されます。 Aは前にフェッチされたNSManagedObjectです。

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] 
            initWithKey:@"Name" 
            ascending:YES]; 

NSArray *lotsOfB = [[[A hasRelationsTo] 
        allObjects] 
        sortedArrayUsingDescriptors: sortDescriptors]; 

これは非常に高速です。シミュレータまたはデバイスに遅延がありません。しかし、あなたはpingbatがないように私はできるだけ多くのオブジェクトを持っていませんでした。私は似たような状況でも、午前

0

。助け

希望:-(

をNSFetchedResultsController悲しい回を使用することはできませんが、それは取りました15秒で "ANY hasParent.label == 'A'"をフェッチする

NSFetchedREsultsControllerを使用する必要があるため、モデルを再構築する必要があります。文字列プロパティを作成し、述語 "hasParent contains%@"を構築します。

私が学んだ教訓は、対多の関係を横断述語を有するBIGパフォーマンスヒットを持っているということです。..

5

あなたはこのように、あなたのAのオブジェクトIDと述語を使用する必要があります。

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

NSEntityDescription *BEntity = [NSEntityDescription entityForName:@"B" inManagedObjectContext:moc]; 
[fetchRequest setEntity:BEntity]; 

NSPredicate *predicate = [NSPredicate 
predicateWithFormat:@"(relationship_to_a = %@)", [yourAInstance objectID]]; 

[fetchRequest setPredicate:predicate]; 

ここで、relationship_to_aは、B管理オブジェクトのAとの関係の名前です。

これが役に立ちます。

Btw:リレーションシップセットのフォルトを使用することを示唆している他のすべての回答には、自分自身で試してみましたが、フェッチするよりも遅かったです。それゆえ、大きなセットでは痛いほど遅くなります。あなたがフェッチすることで、あなたのインスタンスを取得する場合

実際には、あなたはYESにごNSFetchRequestでをrelationshipKeyPathsForPrefetching を設定しようとすることができ、その後、関係内のすべてのオブジェクトは、障害ではありません。しかし、これは私のためには機能しませんでした。