0

長い質問---お時間をいただきありがとうございます。新しいマネージド オブジェクトを保存した後、それらがコア データ データベース内の別のオブジェクトの関係に追加されていることがわかりました。これは、私のコードが setter メソッドを呼び出さず、逆の関係を持たないオブジェクトです。コードを詳しく調べ、ログを使用して発生を可能な限り分離しましたが、説明 (または修正) できない奇妙な動作に遭遇しています。

すなわち:

というエンティティがありますPendingSyncTracker。関係は 1 つだけobjectsToSyncです。この関係でセッター メソッドを呼び出す行をコードにまだ追加していません。これは対多の関係です。を指すBaseEntity。「逆」オプションについては、「逆関係なし」を選択しました。

特定のテーブル ビューをロードすると、3 つのオブジェクトがサーバーからダウンロードされ、管理対象オブジェクトに解析されて保存されます。テーブル ビューがセルの読み込みを開始するまでに、これら 3 つのオブジェクトのうち 2 つが不思議なことにobjectsToSyncリレーションシップに存在します。

NSLogこれらのオブジェクトがセットのメンバーとして最初に見つかる時期を正確に把握するために、コード全体を使用しましたobjectsToSync

NSSet *objectsToSync = [[[SyncEngine sharedEngine] fetchClassNamed:@"PendingSyncTracker" withPredicates:nil][0] valueForKey:@"objectsPendingSync"];
NSLog(@"PendingSyncTracker objectsToSync set (%lu objects): %@", (unsigned long)[objectsToSync count], objectsToSync);

それらがセットに最初に表示される時期に対する答えは、実際には、これらの 2 行のコードを配置する場所と配置しない場所によって異なります。

  • 3 つの新しいコア データ オブジェクトを保存する過程で管理対象オブジェクト コンテキストが保存される前に、オブジェクトがリレーションシップで見つかりません。

  • 新しいオブジェクトを同期エンジンに送信してローカル (MOC がアクセスおよび保存される場所) に保存する Table View Controller に戻るまで、これらの 2 行を使用しないと、ログにそのことが明らかになります。 2 つのオブジェクトが関係に追加されました。

  • MOC を Sync Engine に保存した直後にこれらの 2 行を使用すると、ログは (そこと TVC の両方で) 1 つのオブジェクトのみが関係に追加されたことを示します。

  • MOC を保存する (および TVC に戻す) 直前と直後にこれらの 2 行を使用すると、3 つのログすべてで関係に空のセットが含まれていることがわかります。

  • の冒頭にもこれらの2行がありcellForRowAtIndexPathます。以前のログに関係なく、そのログは常に 2 つのオブジェクトが関係に追加されたことを示します。

BaseEntity同期エンジンで作成された 3 つの管理対象オブジェクトはすべて、 (objectsToSync関係が指す)サブエンティティであるエンティティ タイプとして格納されます。リレーションシップに追加される 2 つのタイプはそれぞれ、相互リレーションシップを持つように定義されていますが、別のオブジェクトではそうではありませんPendingSyncTracker(別のオブジェクトは BaseEntity の subEntity ですが!)。

それで..これらの観察を説明するものは何ですか?これらのオブジェクトはどのように関係に追加されますか?

アップデート:

- (NSArray*) fetchClassNamed:(NSString*)className withPredicates:(id)parameters;
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:className inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // set predicates
    if (!(parameters == nil)) {
        [fetchRequest setPredicate:parameters];
    }

    NSError *error;
    NSArray *fetchedResults = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

    return fetchedResults;
}
4

1 に答える 1

1

まず、何をし[[[SyncEngine sharedEngine] fetchClassNamed...ますか?推測ですが、KVC との関係を設定するために何かを行っています。

また、常に、常に常に逆の関係にある必要があります。まったく使用しない場合でも、Core Data は使用します。逆数がないと、パフォーマンスの問題やデータ破損の可能性など、多くの問題が発生する可能性があります。

逆の関係を追加し、質問を更新してください-fetchClassNamed...

于 2013-08-05T23:03:25.707 に答える