the*_*jaz 30 core-data objective-c nsfetchedresultscontroller nsmanagedobjectcontext ios
我有一个问题几乎与此人描述的问题相同,但它没有得到答案:
这是问题所在:
我有一个使用NSPrivateQueueConcurrencyType和持久性存储协调器集的父MOC设置,它有一个带有NSMainQueueConcurrencyType的子MOC设置.大多数长期努力工作和保存的想法可以在私有MOC上完成,从而使主线程阻止UI.不幸的是,我似乎遇到了导致死锁的几种情况.
如果子MOC(在主线程上)正在使用NSFetchedResultsController执行提取,则会向父上下文发送-executeFetchRequest:它可以创建死锁.这两个操作都是在performBlock的上下文中完成的:对于它们各自的MOC,尽管文档似乎表明在没有performBlock的主线程上使用主线程并发类型MOC是好的.
看起来私有队列正在等待主线程上的子上下文已经锁定的PSC锁.看起来子上下文(在持有PSC锁定时)试图将dispatch_sync分配给父上下文,因此它们都在等待彼此.
是PriveQueue - > MainQueue是支持的配置吗?似乎大多数人仍然在主线程上有父上下文.
主线程看起来像这样:
Run Code Online (Sandbox Code Playgroud)> #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 ()
Run Code Online (Sandbox Code Playgroud)
他还写道:
我开始认为问题出在NSFetchedResultsController上,它始终停留在performFetch:当发生这些死锁时.大多数时候,由于要求它的部分名称,它会因为试图在对象中出错而被卡住.作为测试,我尝试重现FRC的功能并执行executeFetchRequest:然后遍历结果,询问每个对象的部分名称.这不会造成僵局.如果我离开FRC去执行performFetch:在我进行测试后它仍然会死锁.我99%确定FRC与嵌套上下文有同步问题.
问题:有人知道为什么会出现这个问题吗?你知道怎么解决吗?这是一个错误吗?
Mar*_*n R 34
我刚读过这篇SO帖子,其中fabrice truillot de chambrier建议目前不要使用嵌套的上下文.他提到了Core Data Growing Pains 这篇文章.
从那篇文章:
NSFetchedResultsController死锁
你永远不希望你的应用程序死锁.使用NSFetchedResultsController和嵌套上下文,这很容易做到.使用上述相同的UIManagedDocument设置,在将NSFetchedResultsController与主队列上下文一起使用时,在私有队列上下文中执行获取请求可能会死锁.如果你几乎在同一时间开始,几乎100%的一致性.NSFetchedResultsController可能正在获取它不应该的锁.据报道,即将发布的iOS版已经修复了这个问题.
雷达:// 11861499修正了即将发布的版本
这似乎准确描述了您的问题.