-1
@synchronized (self.class)     {
    fetchedObjects = [moc executeFetchRequest:request error:&error];
}

moc は managedObjectContext です

メインスレッドに対応するのは moc です。その moc はすべての MOC の親です。

他のモックはただの子供です。子が executeFetchRequest を実行すると、親 moc も同じ executeFetchRequest を実行することがあります。

私がよく目にするのは、

メインスレッドの外側:

@synchronized (self.class)     {
    fetchedObjects = [moc executeFetchRequest:request error:&error]; //semaphore_wait_trap here
}

メインスレッドで

@synchronized (self.class)     {//_psynch_mutexwait
    fetchedObjects = [moc executeFetchRequest:request error:&error];
}

わかりました...なぜデッドロックですか?メインスレッドのモックはメインスレッドに対応していますが、まったくアクセスされていません。@synchronized で待ちます。では、なぜfetchedObjects = [moc executeFetchRequest:request error:&error];待つのですか?

4

2 に答える 2

4

executeFetchRequest の呼び出しを @synchronize-ing するべきではありません。

このexecuteFetchRequest:error:メソッドは、本質的に、ハードウェアと作業負荷に合わせて動作を適切にスケーリングします。必要に応じて、Core Data は追加のプライベート スレッドを作成して、フェッチ パフォーマンスを最適化します。目的のためにバックグラウンド スレッドを作成しても、絶対的なフェッチ速度は向上しません。ただし、バックグラウンド スレッドまたはキューでフェッチして、アプリケーションのユーザー インターフェイスがブロックされないようにすることが適切な場合もあります。これは、フェッチが複雑な場合や大量のデータを返す場合に、ユーザーに制御を返し、結果が到着したときに結果を表示できることを意味します。

Core Data プログラミング ガイド: 同時実行性

基本的に、多くのオブジェクトを返して処理する場合は、プライベート キュー コンテキストから行うのが最善です (返されたオブジェクトをそのプライベート キューで使用し、メイン キューから処理することができるため)。

メイン キュー コンテキストがある場合は、メイン キューからのみ使用します。

また、子コンテキストはフェッチ要求を親に渡すことで実行します。何が起こるか (私が知る限り) は、述語が永続ストア (SQL) と、チェーン内の各 MOC の保存されていないオブジェクトで評価されるということです。これは、たとえば、述語で使用される getter をオーバーライドすると、メモリ内の保存されていないオブジェクトに対して呼び出されることを意味します (一方、SQL 述語は生の DB 値を使用して比較します)。子コンテキストからキューをブロックすることで、親コンテキストをデッドロックできます。

于 2013-01-15T15:14:29.413 に答える
3

モックは独自のロックを保持しているため、ロックにロックがあります-t1が来ると、ロック1を取得しますが、誰かがすでにフェッチしてロック2を持っているため、ロックされていない可能性がありますが、t1によってブロックされています(待機中)

于 2013-01-15T10:42:59.483 に答える