2012-10-13 14 views
5

複数のスレッドで1つのMOCを使用すると、すべての結果に苦しんだ - メインスレッドでMOCが作成され、別のスレッド。 コードはグローバルシングルトンを使用して同期(@同期)していますが、アプリがクラッシュします。 スレッドごとに別々のMOCを使用すると問題はなくなりますが、NSManagedObjectsをスレッド間で共有することも悪いアプローチと考えられています。コアデータ - 複数のスレッド間でNSManagedObjectsを共有する

私の使用例は次のとおりです。 1)サーバーからXMLをロードして解析し、解析中に新しいNSManagedObjectをデータベースに挿入します。これはすべて別のスレッドで発生します。 2)メインスレッドから、ユーザーはデータベースからデータを読み取るUIと対話します。

どちらのスレッドでも、NSManagedObjectsを使用します。これを修正するように私にどのように提案しますか?私はすでに何度も失敗しました。

ほとんどの場合、エラーが発生してコレクションが変更されている間に、コードが同期されている間にコレクションが変更されていて、反復処理中にコレクションが変更されたり、反復して、私は完了したら保存します。

答えて

8

スレッドごとに1つずつNSManagedObjectContextを使用してください。スレッド間で通信する場合は、スレッドセーフであるNSManagedObjectIDを渡し、スレッドコンテキストからオブジェクトを再度フェッチします。私のアプリケーションでは、コントローラごとに1つのコンテキストを使用することさえあります。

異なるコンテキストを管理するには、NSManagedObjectContextDidChangeNotificationのオブザーバを登録します。この通知処理では、mergeChangesFromContextDidSaveNotification:メソッドを使用して、各コンテキストに通知を渡します。このメソッドはスレッド保存であり、コンテキスト更新をその状態にします。

この後、ビューを更新する必要があります。テーブルビューベースのアプリケーションをお持ちの場合は、NSFetchedResultsControllerをご覧ください。これは、適切なアニメーションで表を自動的に更新するのに役立ちます。テーブルビューを使用しない場合は、UIの更新を自分で実装する必要があります。

5

iOS 5以上しかサポートしていない場合は、NSManagedObjectIDを処理してコンテキストをマージする必要はありません。代わりに新しい並行性タイプNSManagedObjectContextを使用することができます。その後、managedObjectContext:performBlock内で操作を行い、自動的にマージされます。

詳しくは、svenaの回答をご覧ください。 Core Data and Concurrency using NSOperationQueues