2

シナリオ:

SQLite データベースに対して動作するように構成された Magical レコードを使用して IOS を使用しています。デフォルトでは、MR はすべての書き込みをメイン スレッドの親コンテキストにシリアル化するように coredata を構成します。

私が使用するパターンは、メイン スレッドを使用していないときに、MagicalRecord:MR_saveWithBlockAndWait などを使用してコアデータ操作用に別の NSManagedObjectContext を作成することです。Magical record はコンテキストを作成し、それを親コンテキストに接続し、コールバック ブロックで指定した操作を実行し、最後に保存します。重要なのは、操作が完了する前に保存がコミットされることになっていることです。

バックグラウンド スレッドでの作業が終了したら、通常、何かが発生したことを UI に通知します。例: 何かがダウンロード/アップロード/変更されました。

次に、UI スレッドで、メイン スレッドのデフォルト コンテキストを使用して新しいフェッチ リクエストを作成します。問題は、以前にコミットしたばかりの新しいオブジェクトが coredata で見つからない場合があることです。この問題は微妙な競合状態に現れます。UI スレッドがアニメーションやその他の理由でわずかに遅い場合、すべて正常に動作しますが、新しいオブジェクトが見つからない場合があります。

私が読んだことから、フェッチ要求は常にディスクに送られるはずです。MOC にも古いプロパティがありますが、それはキャッシュのみに関するものであり、フェッチ リクエストを実行するとバイパスされるようです。

誰かが同様の問題に遭遇し、洞察を持っていますか? ありがとう。

4

1 に答える 1

1

もちろん。バックグラウンドの管理対象オブジェクト コンテキストで変更を保存しても、UI コンテキストがそのオブジェクトを既に読み込んでいる場合、UI コンテキストは、ストア ファイルではなくキャッシュからデータを提供するだけかもしれません。

複数のコンテキストを使用する通常のアプローチは次のとおりです。

  1. バックグラウンド コンテキストがいつ変更を保存するかがわかるように観察NSManagedObjectContextDidSaveNotificationしてください。

  2. この通知のハンドラーでmergeChangesFromContextDidSaveNotification:、UI コンテキストを呼び出して、他のコンテキストからの変更で更新されるようにします。

mergePolicyデフォルトでは、競合する変更がある場合に放棄するため、おそらく UI コンテキストで を設定する必要があります。

これは、異なるコンテキストによって保存された変更で各コンテキストを更新する必要があるマルチ コンテキスト シナリオに適用されます。

于 2013-10-15T18:43:18.100 に答える