私はコアデータをマルチスレッドで使用しようとしています。バックグラウンドで新しいデータをダウンロードしながら、以前にダウンロードしたデータでアプリケーションを表示したいだけです。これにより、ユーザーは更新プロセス中にアプリケーションにアクセスできます。
NS.
問題は、古いオブジェクトと同じコンテキストで新しいオブジェクトを作成しているときに、BAD_INSTRUCTION例外がスローされる可能性があることです。そのため、新しいデータに別のコンテキストを使用することにしましたが、すべてのオブジェクトを一度終了してから他のコンテキストに移動する方法がわかりません。
パオロ別名スローツリー
Apple Core Dataドキュメントとの同時実行 が開始点です。本当に注意深く読んでください...誤解に何度も噛まれました!
基本的なルールは次のとおりです。
NSPersistentStoreCoordinator
を使用します。スレッドごとにそれらを必要としません。NSManagedObjectContext
を1つ作成します。NSManagedObject
を他のスレッドに渡さないでください。-objectID
を介してオブジェクトIDを取得し、他のスレッドに渡します。その他のルール:
NSManagedObjectContext
の-mergeChangesFromContextDidSaveNotification:
は役に立ちます。繰り返しますが、文書を注意深く読んでください!それは本当に価値があります!
現在[2015年5月] Apple Concurrency with Core Data documentation は、iOS 5の拡張機能をカバーしていないため、コアを使用する最適な方法を示していないため、非常に誤解を招く可能性がありますデータを同時に。 iOS 5には2つの非常に重要な変更があります-親コンテキストと新しい並行性/スレッドタイプです。
これらの新機能を包括的にカバーする文書はまだ見つかりませんでしたが、 WWDC 2012ビデオ「セッション214-コアデータのベストプラクティス」 ですべてが十分に説明されています。
Magical Record はこれらの新しい機能を使用しているため、一見の価値があります。
実際の基本は同じです-管理オブジェクトコンテキストが作成されたスレッドの管理オブジェクトのみを使用できます。
[moc performBlock:]を使用して、適切なスレッドでコードを実行できるようになりました。
MergeChangesFromContextDidSaveNotificationを使用する必要はもうありません。代わりに、子コンテキストを作成して変更を加えてから、子コンテキストを保存します。子コンテキストを保存すると、変更が自動的に親コンテキストにプッシュされ、変更をディスクに保存するには、そのスレッドの親コンテキストで保存を実行するだけです。
これが機能するためには、コンカレントタイプで親コンテキストを作成する必要があります。例:
mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
次に、バックグラウンドスレッドで:
context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
[context setParentContext:mainManagedObjectContext];
<... perform actions on context ...>
NSError *error;
if (![context save:&error])
{
<... handle error ...>
}
[mainManagedObjectContext performBlock:^{
NSError *e = nil;
if (![mainContext save:&e])
{
<... handle error ...>
}
}];
これが、マルチスレッド環境でコアデータを使用して問題に直面するすべての人々に役立つことを願っています。
Apple documentation。 :D
お役に立てれば。
パオロ
追伸Yujiに感謝します。上記のドキュメントでその例を見つけました。