のは、我々が場所のリストを表示する必要があると3つのスレッド上で動作するアプリを持っているとしましょう:(サーバーと 場所を同期するNSManagedObjectContextsとマルチスレッド
- メインスレッド
- メインスレッドの背景Syncを私はDを持っているすべての3つのスレッドで)
- ) バックグラウンドで場所をジオコードする スレッドを(ジオコーディング
編集されたNSManagedObjectContexts
(MOC)。ジオコーディングスレッドで緯度/経度情報が追加されている間に、各MOCが基礎データを変更できる場合(主スレッドはお気に入りに場所を追加できますが、背景同期は場所の名前を変更できます)、アプリはNSManagedObjectContextDidSaveNotification
に登録する必要があります1つのMOCが(メインスレッドのMOCにマージされるのではなく)保存された場合は、mergeChangesFromContextDidSaveNotification
を他のスレッドの対応する他のMOCに広げます。今、私はそれをやっている
原因とそれが正しい感じていない:(
を私は自分れるMOCと、現在実行中のスレッドを保存するために使用する辞書を持っている。れるMOCの1がNSManagedObjectContextDidSaveNotification
をポップするたびに私はこの配列をループし、他のすべてのMOC /スレッドにmergeChangesFromContextDidSaveNotification
を送信します。もちろん、オブザーバもNSThreadWillExitNotification
に追加しました。スレッドの1つがなくなると、スレッド/ MOCを配列から削除できます。辞書の操作がロックされています それは私がちょっと邪魔しているところです
[moc performSelector:@selector(mergeChangesFromContextDidSaveNotification:)
onThread:thread
withObject:notification
waitUntilDone:YES];
れるMOC /スレッド辞書をループするとき、私は私を投げ、次の例外を取得:
[NSManagedObjectContext performSelector:onThread:withObject:waitUntilDone:modes:]: target thread exited while waiting for the perform
どうやら、これは競合状態によって引き起こされます。辞書をループしている間(私はそのオブジェクト配列を抽出している間だけロックしていました)、出口のスレッドの1つ、したがって参照はもはや有効ではありません。私は、ループ全体の前で辞書ロックを置けば、ループ内のコール
[moc performSelector:@selector(mergeChangesFromContextDidSaveNotification:)
onThread:thread
withObject:notification
waitUntilDone:YES];
は、いくつかのケースでは永遠にかかるのでしかし、私は、デッドロックを取得します(理由はまだ知らない)ため、原因となりますアプリ全体がストールする この場合、waitUntilDone:NO
で電話をかけても安全ですか?それはそれを修正するようだ。これで私が誤って開いたパンドラの箱場合、私はちょうど私があなたのアプリケーション構造が危険な状況であなたを入れていると思う....、
よろしく、
セバスチャン