NSManagedObjectContext
を使用してNSMainQueueConcurrencyType
を初期化するのは、そのMOCにNSPrivateQueueConcurrencyType
を使用して初期化された子MOCがある場合のみですか?
背景を説明すると、私のアプリは従来の構造で、メインテーブルビューはNSFetchedResultsController
によって駆動され、データは独自のMOCを持つNSOperation
サブクラスを使用してWebサービスから非同期にインポートされます。その状況で両方のMOCがNSConfinementConcurrencyType
(デフォルト、私は信じています)を使用する必要があるのか、メインスレッドのフェッチされた結果コントローラーに関連付けられたMOCがNSMainQueueConcurrencyType
を使用する必要があるのかわかりませんでした。バックグラウンドMOCはNSConfinementConcurrencyType
を使用する必要があります。
まず、CoreDataの新しいコンテキストタイプに関するレシピ。
NSMainQueueConcurrencyType
は、メインディスパッチキュー、つまりメインスレッドに関連付けられたコンテキストを作成します。このようなコンテキストを使用して、メインスレッドで実行する必要のあるオブジェクト(UI要素など)にリンクできます。
NSPrivateQueueConcurrencyType
は、操作するプライベートディスパッチキューを作成および管理します。新しいメソッドを使用する必要がありますperformBlock:
またはperformBlockAndWait:
。次に、コンテキストは、渡されたブロックを独自のプライベートキューで実行します。
最後に、NSConfinementConcurrencyType
はデフォルトのタイプであり、作成されたスレッド内で使用できますのみ。したがって、NSOperation
内で、適切な方法で使用しました。簡単なメモ。子コンテキストとして使用する場合は、「キューコンテキスト」(NSMainQueueConcurrencyType
またはNSPrivateQueueConcurrencyType
)が必要です。
さて、あなたの質問について。
NSMainQueueConcurrencyTypeを使用してNSManagedObjectContextを初期化するのは、そのMOCにNSPrivateQueueConcurrencyTypeを使用して初期化された子MOCがある場合のみですか?
いいえ、必要ありません。はい、バックグラウンドでいくつかの作業を行い、取得したオブジェクトをメインコンテキストにプッシュするプライベートコンテキストを設定できますが、逆に行います。マスターコンテキストとしてNSPrivateQueueConcurrencyType
を使用し、NSMainQueueConcurrencyType
前者の子コンテキストとして。このように、メインコンテキストはメモリ内にあるオブジェクトのみを処理します。ディスクへの保存は、プライベートキューによってのみ実行されます。
このアプローチは、UIManagedDocument
クラスによって使用されます。ディスクへの保存は、バックグラウンドスレッド(プライベートキュー)で実行されます。このようにして、UIはフリーズしません。
NSMainQueueConcurrencyType
は、主にUIにリンクされたコンテキスト用です。
UIの応答性を維持するために、ほとんどのビジネスロジックはバックグラウンドスレッドと「バックグラウンド」コンテキストで実行するのが最適です。ただし、UI自体は、ある時点でコンテキストを使用する必要があります。つまり、NSMainQueueConcurrencyType
です。
NSMainQueueConcurrencyType
の子コンテキストは、変更を一度に保存できる、つまり親コンテキストにコミットできるペインの編集に適しています。親はNSMainQueueConcurrencyType
を使用する必要はありません。
NSConfinementConcurrencyType
がデフォルトのタイプです。コンテキストを現在のスレッドにリンクします。ちなみに、ほとんどの場合、メインスレッドです。デフォルトのタイプに依存するのではなく、最も単純なアプリケーションに依存する必要があります。 NSMainQueueConcurrencyType
とNSPrivateQueueConcurrencyType
は、すべてのコンテキストでどのキューが使用されているかを正確に把握しているため、最適です。