ここでこの人が説明した問題とほぼ同じ問題がありますが、回答がありません。
問題は次のとおりです。
NSPrivateQueueConcurrencyType と永続ストア コーディネーター セットを持つ親 MOC セットアップがあり、NSMainQueueConcurrencyType を持つ子 MOC セットアップがあります。長いハードワークと保存のほとんどはプライベート MOC で行うことができ、メイン スレッドが UI をブロックすることから解放されます。残念ながら、デッドロックを引き起こすいくつかの状況に遭遇しているようです。
子 MOC (メイン スレッド上) が NSFetchedResultsController でフェッチを実行している場合、親コンテキストに -executeFetchRequest が送信されます。デッドロックが発生する可能性があります。両方の操作は、performBlock: のコンテキスト内でそれぞれの MOC に対して行われますが、ドキュメントは、メイン スレッド上で performBlock: を使用せずにメイン スレッドの同時実行型 MOC を使用することを示しているようです。
プライベート キューは、メイン スレッドの子コンテキストが既にロックしている PSC ロックを待機しているようです。子コンテキスト (PSC ロックを保持している間) が親コンテキストに dispatch_sync しようとしているように見えるため、両方が互いに待機しています。
PriveQueue -> MainQueue はサポートされている構成ですか? ほとんどの人はまだメインスレッドに親コンテキストを持っているようです。
メインスレッドは次のようになります。
> #0 0x960f6c5e in semaphore_wait_trap () > #1 0x04956bb5 in _dispatch_thread_semaphore_wait () > #2 0x04955c8f in _dispatch_barrier_sync_f_slow () > #3 0x04955dea in dispatch_barrier_sync_f () > #4 0x01797de5 in _perform () > #5 0x01798547 in -[NSManagedObjectContext(_NestedContextSupport) newValuesForObjectWithID:withContext:error:] () > #6 0x0176416b in _PFFaultHandlerLookupRow () > #7 0x01763f97 in -[NSFaultHandler fulfillFault:withContext:forIndex:] () > #8 0x01763b75 in _PF_FulfillDeferredFault () > #9 0x017639f2 in _sharedIMPL_pvfk_core () > #10 0x017681a0 in _pvfk_11 () > #11 0x0001b322 in -[FBUser sectionName] at /Users/mlink/Code/x/x/FBUser.m:62 > #12 0x011a8813 in _NSGetUsingKeyValueGetter () > #13 0x017a0652 in -[NSManagedObject valueForKey:] () > #14 0x011ab8d5 in -[NSObject(NSKeyValueCoding) valueForKeyPath:] () > #15 0x01851f72 in -[NSFetchedResultsController(PrivateMethods) _sectionNameForObject:] () > #16 0x01853af6 in -[NSFetchedResultsController(PrivateMethods) _computeSectionInfo:error:] () > #17 0x01850ea6 in -[NSFetchedResultsController performFetch:] () > #18 0x0003a4fc in __62-[SYFriendsTableViewController updateFetchedResultsController]_block_invoke_0 () > #19 0x01797af3 in developerSubmittedBlockToNSManagedObjectContextPerform () > #20 0x049554f0 in _dispatch_main_queue_callback_4CF () > #21 0x01b3e833 in __CFRunLoopRun () > #22 0x01b3ddb4 in CFRunLoopRunSpecific () > #23 0x01b3dccb in CFRunLoopRunInMode () > #24 0x023d6879 in GSEventRunModal () > #25 0x023d693e in GSEventRun () > #26 0x0089aa9b in UIApplicationMain () > #27 0x00002656 in main at /Users/mlink/Code/x/x/main.mm:16
プライベート キュー スタックは次のようになります。
#0 0x960f8876 in __psynch_mutexwait ()
#1 0x97e9e6af in pthread_mutex_lock ()
#2 0x0172ec22 in -[_PFLock lock] ()
#3 0x0172ebfa in -[NSPersistentStoreCoordinator lock] ()
#4 0x01746a8c in -[NSManagedObjectContext(_NSInternalAdditions) lockObjectStore] ()
#5 0x01745030 in -[NSManagedObjectContext executeFetchRequest:error:] ()
#6 0x0009d49f in -[NSManagedObjectContext(Additions) executeFetchRequest:] at /Users/mlink/Code/objc/C/C/NSManagedObjectContext+Additions.m:44
#7 0x0002177f in +[FBUser usersForFbids:inManagedObjectContext:] at /Users/mlink/Code/x/x/FBUser.m:435
#8 0x00021fc0 in __77+[FBUser updateUserFromGraphValues:inManagedObjectContext:completionHandler:]_block_invoke_0 at /Users/mlink/Code/x/x/FBUser.m:461
#9 0x0180f9f3 in developerSubmittedBlockToNSManagedObjectContextPerform_privateasync ()
#10 0x04954ecf in _dispatch_queue_drain ()
#11 0x04954d28 in _dispatch_queue_invoke ()
#12 0x049544af in _dispatch_worker_thread2 ()
#13 0x97ea1b24 in _pthread_wqthread ()
#14 0x97ea36fe in start_wqthread ()
彼は次のようにも書いています。
問題は、これらのデッドロックが発生したときに常に performFetch: でスタックしている NSFetchedResultsController にあると考え始めています。ほとんどの場合、オブジェクトのセクション名を要求した結果として、オブジェクトをフォールトしようとしてスタックします。テストとして、FRC の動作を再現して executeFetchRequest: を実行してから、各オブジェクトにセクション名を要求する結果を反復処理しました。そして、これはデッドロックを引き起こしません。FRC をそのままにして performFetch を実行すると、テストを実行した後もそこでデッドロックが発生します。FRC にネストされたコンテキストとの同期の問題があることは 99% 確信しています。
質問: この問題が発生する理由を知っている人はいますか? あなたはそれを解決する方法を知っていますか?これはバグですか?