5

私はまだコアデータを新しくしていますが、NSManagedObjectContextを渡す必要がある理由を理解しようとしています。私が理解しているように、複数のスレッドが同じコンテキストに影響を及ぼさないようにコンテキストを渡す必要がありますが、このパターンは時々反パターンと見なされます。hereコンテキストパターン?なぜCore Dataはそれを必要としますか?

コアデータは理論的にはこのパターンを使用しないスレッドセーフな方法で実装できますか?どのように他のORM(RubyのActiveRecordなど)はこのパターンを避けるのですか?たとえば、CoreDataは、extensionのようなNSManagedObjectごとの保存メソッドを実装できませんでした。この軽いフレームワークはマルチスレッドを処理しませんが、NSManagedObjectsは内部コンテキストを公開するために何らかの種類の内部GCDキューを使用できませんでした。

大変なことがあれば申し訳ありません。

+1

+1良い質問です。私は大きな文脈がしばしば反パターンと見なされることを知っていますが、アップルがトイレトイレを突っ込むために屋根板を渡すジュニアプログラマと同じようにそれを乱用しているようには思われません。 'NSManagedObjectContext'は多くのことをメソッドで処理しますが、すべてのエンティティをすぐに利用できるようにする必要はなく、同じモデルを共有している2つのエンティティが互いに知り合う必要はありません。 – Joe

答えて

5

NSManagedObjectContextは、永続ストア(XML、SQLiteなど)が通常オブジェクトグラフのディスク上のコンテナを表すのと同じように、アプリケーションオブジェクトグラフのメモリ内コンテナです。

いくつかの利点が、このアプローチにあります

  1. 断層オブジェクトの集合に適用することができ、又はCoreDataの場合にオブジェクトグラフ全体
  2. それがアプリケーションを強制するための便利な抽象化ですバッチはI/Oです。
  3. オブジェクトグラフ(NSFetchRequestsなど)全体で効率的に操作を実行できる単一の接点を提供します。
  4. 個々のオブジェクトだけでなく、オブジェクトグラフにも元に戻すことができます。

CoreDataはORMフレームワークではなく、オブジェクト永続性フレームワークであることを覚えておくことも重要です。 CoreDataの主な責任は、ディスク上の永続フォーマットで格納されたデータへのアクセスをより効率的にすることです。ただし、リレーショナルデータベースの機能をエミュレートしようとはしません。

並行性については、Mac OSXの次期リリースで新しい同時実行モデルが導入されました。詳細については、developer.apple.comを参照してください。

しかし、抽象的に言えば、管理オブジェクトコンテキスト用に選択された並行性モデルは、コンテキストパターン自体よりも個々のアプリケーションの仕様に関連しています。通常、NSManagedObjectContextのインスタンスはスレッド間で共有されるべきではありません。

各スレッドがNSAutoReleasePoolのインスタンスを必要とするのと同じ方法で、各スレッドも自身のMOCを持つ必要があります。こうすることで、スレッドの実行が完了すると、ディスク上のストアへの変更をコミットしてコンテキストを解放し、スレッドで処理されたオブジェクトが消費するすべてのメモリを解放することができます。

これは、特定のアプリケーションのライフサイクル中に単一のコンテキストがシステムリソースを継続的に消費できるようにするよりはるかに効率的なパラダイムです。もちろん、コンテキストでも-resetを呼び出すことでこれを行うことができます。コンテキストによって使用されているすべてのNSManagedObjectがフォールトに戻されます。

0

スレッドごとに1つのNSManagedObjectContextが必要です。したがって、メインスレッドでUIを塗りつぶすようにし、長い操作ではバックグラウンドスレッドごとに別のUIを用意します。結果を他のスレッドからマージするには、メインMOCに変更されたものをすばやくマージするための通知が表示されます。

+0

マージポリシーのタイプを設定し、それ自身で内部的に作成されたオブジェクトをマージすることに比べて、このマージを自分自身(CoreDataが提供している場合)に対して行うことに利点がありますか?これを行うことができれば、APIをもっと簡単に使用できるようになると思われます。 – donalbain