0

更新:以下のMartin Rは、私の質問にほぼ答える非常に明確な(そして簡潔な!)回答を提供してくれました。私は言い換えるべきだと思います:

別の NSManagedObject に接続されている NSManagedObjects のフェッチが、 を呼び出すときに機能しない理由を考えていただけますか?prepareForDeletionそのようなオブジェクトは、削除されるオブジェクトに 1 対 1 で接続されています。

prepareForDeletionオブジェクトの子を削除する必要があるかどうかを判断する前にエンティティ チェックを実行できるように、呼び出すことができる必要があります。


1 対 1 の関係の場合、Core Data でオブジェクトの子オブジェクトを削除するためのトリックはありますか?

単一の NSManagedObject を削除すると、その子 NSManagedObjects もprepareForDeletion. 削除の直前に一連のデバッグ NSLog ステートメントを実行すると、すべての関係が適切に設定されていることがわかります。ただし、実際にオブジェクトを削除しようとすると、NSFetchRequest を介してこれらのオブジェクトの一部 (すべてではない) をフェッチしようとすると、空の配列が返されるため、これらの関係の多く (すべてではない) が失われているように見えます。

見つかったオブジェクトをフェッチする方法と見つからないオブジェクトをフェッチする方法の違いを理解できないようです。見つかったオブジェクトは逆対多の関係であり、見つからないオブジェクトは1対1であるということを除いて-1 つの関係:-/

「メイン」オブジェクトを削除するには、単に を呼び出し[managedObjectContext deleteObject:mainObject];、メイン オブジェクトのプライベート API 内でprepareForDeletion次のように上書きしました。

- (void)prepareForDeletion
{
//    [super prepareForDeletion]; // commented but uncommenting doesn't change results
    [MyDataManager deleteChildOneForMainObject:self];
    [MyDataManager deleteChildrenTwoForMainObject:self];
    [MyDataManager deleteChildrenThreeForMainObject:self];
}

MyDataManager、クラス メソッドのみを含むカスタム NSObject です。次に、MyDataManager は、次のような方法で管理対象オブジェクト コンテキスト内の対応する NSManagedObjects を検索します。

- (BOOL)deleteChildOneForMainObject:(MainObject *)mainObject
{
    NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"ChildOne" inManagedObjectContext:managedObjectContext];
    [fetch setEntity:entity];
    [fetch setPredicate:[NSPredicate predicateWithFormat:@"(mainObject == %@)", mainObject]];
    NSError *error;
    NSArray *childOnesToDelete = [managedObjectContext executeFetchRequest:fetch error:&error];
    if (childOnesToDelete.count > 1)
    {
        NSLog(@"[WARNING] More than one ChildOne for mainObject found; deleting all");
    }
    NSLog(@"[TEST] Deleting %i ChildOnes", childOnesToDelete.count);
    for (ChildOne *childOne in childOnesToDelete)
    {
        [managedObjectContext deleteObject:childOne];
    }
    if ([managedObjectContext save:&error]) return YES;
    else NSLog(@"[WARNING] Save error for function [deleteChildOneForMainObject:]");
    return NO;
}

ここでも、タイプ「MainObject」の各 NSManagedObject は、「ChildOne」と 1 対 1 の関係を持ち、「ChildTwo」および「ChildThree」とは 1 対多の関係を持ちます。"Child One"、"ChildTwo"、および "ChildThree" はすべて、"MainObject" と対 1 の関係にあります。

4

2 に答える 2

1

関係に「削除ルール」を適切に設定すると、「依存」オブジェクトの削除をCoreDataで自動的に処理できます。この場合、設定できます

  • MainObjectからChildX、「Cascade」への関係のルールを削除します。
  • ChildXからMainObject、「Nullify」への逆の関係のルールを削除します。

つまり、

  • MainObjectが削除されると、関連するChildXオブジェクトも削除されます。
  • ChildXオブジェクトが削除されると、関連するMainObjectのリレーションシップ値NULLに設定されます。
于 2013-01-02T21:29:12.897 に答える
1

だから私はついにIRCを私のために働かせました!また、#iphonedev チャンネルの親切な人が次の洞察を提供してくれました。

• (Martin R が言ったように) Core Data モデルを構築するためのビジュアル インターフェイスを我慢し、提供された [削除ルール] ドロップダウン メニューを使用して削除ロジックを作成する必要があります。("Utilities" の右側のペインで、チーズのくさびのように見える 3 番目のタブ。) "Cascade" と "Nullify" が最も有用な値です。

• 「削除ルール」は一方向であり、各関係に固有であるため、かなりの程度の制御が可能です。

• 提供された NSManagedObject と 1 対 1 の関係を持つ NSManagedObject を取得する代わりに、プロパティを使用します。この関係は定義上 1 対 1 であるため、フェッチを「保護」メカニズムとして使用するのは愚かで不要です。したがってYingYangオブジェクトがある場合は、[managedObjectContext deleteObject:ying.yang]またはを実行するだけ[managedObjectContext deleteObject:yang.ying]です。

最終的prepareForDeletionに、Martin Rの回答によると、カスケード削除に関してのみ関連がありました。

于 2013-01-03T06:57:32.190 に答える