2

次のようなモデルがあります。

ここに画像の説明を入力

コードでは、A は複数の B を持つことができますが、C ごとに 1 つの B しか持たないことを強制しています。

私がやりたいことは、与えられた C のすべての As を B でグループ化してリストすることです。ここで、C から始めて、すべての B のセットを取得し、次にすべての As のセットを取得すると、これはかなり簡単です。それぞれのB.

私がやりたいのは、NSFetchedResultsController を使用して As をリストすることです。「ANY bc MATCHES myC」を使用して C でフィルター処理できますが、正しい B でグループ化する方法がわかりません。

言い換えれば、A には多くの B があるので、どれが私の C に属しているかをどのように判断し、それを NSFetchedResultsController で使用するのでしょうか? それは可能ですか?

4

1 に答える 1

1

安価なハック アプローチ:

nameOfRelevantBobjectのようなものと呼ばれるカテゴリ メソッドを追加し、グローバルとしてA設定しますmyC(または、おそらく、それをファイル ローカル スタティックに格納する A のクラス メソッドに渡します) 。nameOfRelevantBsectionNameKeyPathNSFetchedResultsController

nameOfRelevantBは、指定された C に一致する B を見つけて返します。

明らかな欠点は、関連する C が一度に 1 つしかないことです。

アプリでフェッチされた結果コントローラーがキューまたはスレッドと 1 対 1 の関係を持ち、関連する C をキューまたはスレッド コンテキストとして格納するというルールを推進することで、それを改善できますが、UITableViewDataSourceとにかく順番にマニュアルを書く必要があります。結果をメイン キュー/スレッドに移植します。

カスタム データ ソースを作成する場合はNSFetchedResultsControllerDelegate、[file static] グローバルを避けて、物事を独自のセクションに分割するようにすることもできます。

より徹底的な解決策:

サブクラスをオーバーライドvalueForUndefinedKey:してNSManagedObject、関連する C をobjectID直接キー パスに入れることができます。管理対象オブジェクト ID にはURIRepresentationとが含まれているため、これは明示的に安全です。次に、各 A はキー パスから文字列 URI を取得し、そのコンテキストの永続ストア コーディネーターに問い合わせてから、関連する C に到達するためにコンテキストに問い合わせることができます。C を取得すると、適切な B からタイトルを返すことができます。NSURLabsoluteStringmanagedObjectIDForURIRepresentationexistingObjectWithID:error:

それは、グローバルな状態がなくても、あなたが望むものを達成するでしょう。NSFetchedResultsControllerまた、セクションを決定できるキーパスを指定して、直接使用することもできます。

したがって、たとえば(ここに直接入力、テストされていません)

// get a URI for the relevant myC and prefix it with an '@'
// so that it's definitely clearly not an ordinary property
fetchedResults.sectionNameKeyPath = 
        [NSString stringWithFormat:@"@%@", 
              [[myC.objectID URIRepresentation] absoluteString]];

... in your subclass for A ...

- (id)valueForUndefinedKey:(NSString *)key
{
    // check that the key begins with the magic '@' symbol
    if(![key length] || [key characterAtIndex:0] != '@')
        return [super valueForUndefinedKey:key];

    // get the original URL
    NSString *URLString = [key substringFromIndex:1];
    NSURL *URL = [NSURL URLWithString:URLString];

    // transform the URL into the relevant instance of C
    NSManagedObjectID *objectID = [self.context.persistentStoreCoordinator
                  managedObjectIDForURIRepresentation:URL];
    NSError *error = nil;
    MyCClass *myC = [self.context existingObjectWithID:objectID error:&error];

    // check that we got an appropriate instance and didn't
    // generate an error
    if(!myC || error) return [super valueForUndefinedKey:key];

    /*
        code here to find the appropriate B and return a suitable title
    */
}

主な注意点は、オブジェクト ID、したがって URI が、オブジェクトの最初の作成とその最初の保存の間で変更される可能性があることです。コンテキストを既に保存している場合、オブジェクト ID は、オブジェクトがストアにある限り同じままです。

于 2012-11-20T23:02:51.403 に答える