3

私は今日、私が発見したことに本当に困惑しています。

すべてのコンテキストが同じCoreData永続ストアを使用している限り、コンテキストを保存した後、一方のコンテキストでの変更はもう一方のコンテキストに表示されるはずだと思いました。

たとえば、ビューコントローラAIには1つのコンテキスト(コンテキストA)があり、ビューコントローラBには別のコンテキスト(コンテキストB)があります。これで、コンテキストAとコンテキストBの両方が同じ永続ストアを指します。

コンテキストAでは、永続ストアから管理対象オブジェクトをフェッチし、管理対象オブジェクトのプロパティを更新してから、managedObjectContext保存操作を使用して変更を永続ストアに保存し直しました。

ここで、2番目のView Controllerを開き、同じ永続ストアからフェッチリクエストを実行しますが、シミュレーターを再起動するまで、2番目のViewControllerは更新されたプロパティの変更を認識しません。

本当に奇妙なことは、新しい管理対象オブジェクトを永続ストアに初めて挿入する場合、コントローラーBは変更を認識しますが、その後の変更は表示されないことです。

長い戦いの末、この問題はすでに修正されています。同じ永続ストアを共有する2つの別々のコンテキスト(もちろん両方ともメインスレッド上)があると、シミュレーターが再起動するまで変更が表示されない理由を知りたいだけです。

私がどのように修正したかを知りたい人のために、新しいコンテキストを割り当てる代わりに、コントローラーAとBの両方が継承するベースビューコントローラーで(したがって、コントローラーAとBが2つの別々のコンテキストを持っている理由)、アプリデリゲートのコンテキストを参照するベースビューコントローラー(その結果、コントローラーAとBは同じコンテキストを指すようになりました)。

これが私が見ているものを説明する図です:

ここに画像の説明を入力してください

2番目のViewControllerでフェッチされた結果の値は、古い値です。

一部のデータを永続ストアにコミットすると、managedObjectContext save:が実際に永続ストアに変更を加えるのは、アプリの結果。

4

1 に答える 1

1

張、

詳細がなければ、問題を理解するのは困難です。

簡単な提案は、アプリ内の2つの異なるコンテキスト間の変更をマージするかどうかを確認することです。つまり、メインコンテキストが他のコンテキストからの変更をマージすることを確認する必要があります。これは、次のように簡単に実現できます。

この通知に登録します。たとえば、あなたAppDelegateまたはあなたがCoreDataスタックを作成している場合です。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextChanged:) name:NSManagedObjectContextDidSaveNotification object:nil];

変更をマージするcontextChanged:メソッドを実装します。

- (void)contextChanged:(NSNotification*)notification
{
    if ([notification object] == [self managedObjectContext])
        return;

    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:@selector(contextChanged:) withObject:notification waitUntilDone:YES];
        return;
    }

    [[self managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];
}

詳細については、MarcusZarraチュートリアルを参照してください。

さらに、テーブルを組み合わせて使用​​する場合は、NSFetchedResultsControllerデリゲートのメソッドを実装することを忘れないでください。詳細については、NSFetchedResultsControllerDelegateクラスを参照してください。

お役に立てば幸いです。

于 2012-09-08T11:16:04.603 に答える