10

私が持っているものと欲しいもの:

私は一対多の関係A <--->> Bを持っています(対多の部分は順序付けられています)。

  • A を削除する場合、A と関係のあるすべての B も削除する必要があるため、A と B の関係の削除ルールはカスケードに設定されています-> 正常に動作します
  • B を削除する場合、A に戻る関係のみをクリアする必要があるため、B と A の関係の削除ルールは無効に設定されます -> 機能しません(遅延後のみ)

問題の説明:

したがって、この質問「Core Data Nullify ルールが機能しませんか?」で述べられているのとまったく同じ問題があります。: A と関係のある B を削除し、その直後に A と関係がある残りの B の数を数えますが、以前と同じです。その質問で受け入れられた答えは、nullify が行うことは次のとおりであるため、nullify の代わりにカスケードを使用することでした。

Nullify は、オブジェクトが削除されると、ポインタを null に設定します。ポインターの配列がある場合、それは削除されず、null に設定されます。

その答えには2つの問題があります:

  1. この場合、カスケードは間違ったルールであると確信しています。これは、B を削除するときに A も削除するためです。これは私が達成したいことではありません。(それでも試してみたところ、結果は期待どおりでした:Aも削除されました)。
  2. コレクションは、NSNull シングルトンを使用する場合を除いて、その要素の 1 つとして null を持つことはできません。したがって、これが無効化ルールの機能であるとは思えません。

少し実験した後、B のインスタンスを削除するとすぐに削除されますが、A との関係はすぐには削除されず、少し遅れてのみ削除されることがわかりました。

// Method is called by pressing a button
-(void)removeLastBOfA:(A *)instanceOfA
{
    // Prints 4
    NSLog(@"fetch all b's count before:%d", [context fetchAllBs].count);
    // Prints 4
    NSLog(@"A's relation to B count before: %d", instanceOfA.relationToB.count);

    [context deleteObject:[instanceOfA.relationToB lastObject]];

    // Prints 3
    NSLog(@"fetch all b's count after:%d", [context fetchAllBs].count);
    // Prints 4, but should be 3. Last Object of A's relationToB is still the object that was deleted
    NSLog(@"A's relation to B count after: %d", instanceOfA.relationToB.count);

}

ボタンを押して、その間に何もせずに上記のメソッドを再度呼び出すと、関係が突然更新され、「A と B の関係の前のカウント: 3」が出力されます。そのため、無効化削除ルールは希望どおりに機能しますが、少し遅れます。

質問:

  1. 私が述べた2つの問題は有効ですか?
  2. nullify が遅延後にのみリレーションを更新するのはなぜですか? その遅延は何ですか? または、NSManagedObject を削除した後、どの時点で関係が更新されますか?
4

2 に答える 2

16

はい、あなたは正しいです。答えは正しくありません。2点目について。メソッド -deleteOdject は、オブジェクトを削除済みとしてマークするだけで、期待どおりにオブジェクトを削除しません。削除を完了するには、管理対象オブジェクトのコンテキストを保存する必要があります。その後、nullify ルールが期待どおりに機能することがわかります。この時点でコンテキストを保存したくない場合は、次の 2 つの方法に従うことができます。

  1. リレーションシップを明示的に削除します。

    NSManagedObject* objectToDelete = [instanceOfA.relationToB lastObject];
    [context deleteObject:objectToDelete];
    NSMutableSet* relationships = [instanceOfA mutableSetValueForKey:@"relationToB"];
    [relationships removeObject:objectToDelete];
    
  2. コンテキストに将来の変更を処理するように依頼します (これは、削除による変更を計算することを意味します)。

    [context processPendingChanges];
    

あなたの例では:

[context deleteObject:[instanceOfA.relationToB lastObject]];
[context processPendingChanges];
// Prints 3
NSLog(@"fetch all b's count after:%d", [context fetchAllBs].count);
NSLog(@"A's relation to B count after: %d", instanceOfA.relationToB.count);

その後、期待される結果が表示されます。

NSManagedObjectContext は-processPendingChanges、実行ループの最後または実行時に単独で実行される-save:ため、遅延が発生します。

それが役に立てば幸い。

于 2013-02-12T18:31:26.767 に答える
0

Core Data オブジェクトへの変更が完了したら、管理対象オブジェクト コンテキストでsave:を呼び出す必要があります。保存操作によってすべての関係が更新されると思います。

于 2013-02-12T17:55:42.523 に答える