2

解決策が見つからないように見える興味深い問題があります。'main' と 'backing' という 2 つのマネージド オブジェクト コンテキストがあります。「メイン」は NSMainQueueConcurrencyType で作成され、「バッキング」は「NSPrivateQueueConcurrencyType」で作成されます。さらに、'backing' が main の親として設定されています。

バッキング MOC で (潜在的に高価な) 書き込み操作を実行し、それらの変更を (完了時に) メイン コンテキストにバブルアップさせ、NSFetchedResultsController の使用により UI を更新したいと考えています。私の問題は次のとおりです。

例として、いくつかのコードを示します。

[appDelegate.backingContext performBlock:^{

    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Parent"];
    NSArray *objects = [appDelegate.backingContext executeFetchRequest:fetchRequest error:nil];
    for(Parent *parent in objects) {
        NSMutableOrderedSet *children = [parent mutableOrderedSetValueForKey:@"children"];
        for(Child *child in children) {
            [appDelegate.backingContext deleteObject:child];
        }
        [children removeAllObjects];

        for(int i=0;i<3;i++) {
            Child *child = [NSEntityDescription insertNewObjectForEntityForName:@"Child"
                                                         inManagedObjectContext:appDelegate.backingContext];
            child.name = [NSString stringWithFormat:@"Child #%i", i];
            [children addObject:child];
        }
    }

    [appDelegate.backingContext save:nil];
}];

そして私のアプリデリゲートで

- (void)mergeContextChanges:(NSNotification *)notification {
    [self.mainContext performBlock:^{
       NSLog(@"Before merge: updates - %i, inserts - %i, deletes - %i",
             self.mainContext.updatedObjects.count,
             self.mainContext.insertedObjects.count,
             self.mainContext.deletedObjects.count);
       [self.mainContext mergeChangesFromContextDidSaveNotification:notification];
       NSLog(@"After merge: updates - %i, inserts - %i, deletes - %i",
             self.mainContext.updatedObjects.count,
             self.mainContext.insertedObjects.count,
             self.mainContext.deletedObjects.count);
   }];
}

変更がマージされた後のログの内容は次のとおりです-

2013-04-03 00:51:40.476 CoreDataTest[41617:c07] Before merge: updates - 0, inserts - 0, deletes - 0
2013-04-03 00:51:40.477 CoreDataTest[41617:c07] After merge: updates - 0, inserts - 0, deletes - 3

メイン コンテキストが、削除待ちの 3 つのオブジェクトを報告していることに注意してください。私が知る限り、これは正しくありません - mergeContextChanges をすべきではありません: (そうでなければ完全に手付かずの) コンテキストの状態が保留中の変更を表示しないようにしますか? この方法のポイントは、変更が永続ストアに既にコミットされていることです。

ここで何が欠けていますか?

4

2 に答える 2

2

のドキュメントにmergeChangesFromContextDidSaveNotification:は次のように書かれています:

このメソッドは、他のコンテキストで更新されたすべてのオブジェクトを更新し、新しく挿入されたオブジェクトでエラーを発生させ、削除されたオブジェクトに対して deleteObject: を呼び出します

これは(私が読んだように)あなたの結果と一致しています。

于 2013-04-03T14:47:23.123 に答える
0

これらのオブジェクトは、メイン コンテキストで (削除される前に) フェッチされた可能性があります。
mainContext の親がバッキングであるため、これらの変更を親コンテキストにコミットできます (mainContext で保存を実行します)。
永続ストアにはコミットされず、親コンテキストにのみコミットされるため、保存に時間がかかることはありません。

アプリケーションの別のフローによって保存されるまで、これらの項目をメイン コンテキストに保持できます。
UI はこれらのアイテムの削除に応答します。

于 2013-04-03T06:31:30.843 に答える