我几天来一直在反对这一点,并且不能为我的生活找出正在发生的事情。我对Core Data非常环保,但我知道它足以避免死锁情况。但是对于这个项目,我决定尝试合并AFIncrementalStore。我构建了一个示例项目来测试APIClient,以便适当地映射键/值而不会弄乱我的实际项目。它完美无缺。
现在我在我的实际项目中使用它,但事情很糟糕。 NSFetchedResultsController用于UITableViewController,它被推离屏幕(在菜单中滑动类似于Facebook应用程序)。大约50%的时间我没有陷入僵局。我确保NSFetchedResultsController managedObjectContext与我的AppDelegate相同。几乎所有设置都与AFIncrementalStore示例相同。甚至我的样本项目也可以完美地测试用法。
这是我在死锁期间暂停时Debug Navigator的图像。看起来问题出在AFIncrementalStore的背景上下文和主线程的上下文之间。但是我不知道该怎么办,因为我没有写AFIncrementalStore而且只是偏离了现有的docs / examples。
编辑:添加第二个线程的回溯
thread #2: tid = 0x2103, 0x925d180e libsystem_kernel.dylib`semaphore_wait_trap + 10
frame #0: 0x925d180e libsystem_kernel.dylib`semaphore_wait_trap + 10
frame #1: 0x0258cf08 libdispatch.dylib`_dispatch_thread_semaphore_wait + 16
frame #2: 0x0258ab3a libdispatch.dylib`_dispatch_barrier_sync_f_slow + 149
frame #3: 0x0258aa5c libdispatch.dylib`dispatch_barrier_sync_f + 37
frame #4: 0x00b64c8b CoreData`_perform + 187
frame #5: 0x00b67659 CoreData`-[NSManagedObjectContext(_NestedContextSupport) managedObjectContextDidUnregisterObjectsWithIDs:] + 73
frame #6: 0x00bdf2db CoreData`__97-[NSManagedObjectContext(_NestedContextSupport) managedObjectContextDidUnregisterObjectsWithIDs:]_block_invoke_0 + 75
frame #7: 0x00b64cc1 CoreData`internalBlockToNSManagedObjectContextPerform + 17
frame #8: 0x0259b014 libdispatch.dylib`_dispatch_client_callout + 14
frame #9: 0x0258ad5f libdispatch.dylib`_dispatch_barrier_sync_f_invoke + 58
frame #10: 0x0258aaa3 libdispatch.dylib`dispatch_barrier_sync_f + 108
frame #11: 0x00b64c8b CoreData`_perform + 187
frame #12: 0x00b67659 CoreData`-[NSManagedObjectContext(_NestedContextSupport) managedObjectContextDidUnregisterObjectsWithIDs:] + 73
frame #13: 0x00b71c8c CoreData`-[NSManagedObjectContext(_NSInternalAdditions) _disposeObjects:count:notifyParent:] + 444
frame #14: 0x00b71305 CoreData`-[NSManagedObjectContext(_NSInternalAdditions) _dispose:] + 597
frame #15: 0x00b70e15 CoreData`-[NSManagedObjectContext _dealloc__] + 325
frame #16: 0x00bd872f CoreData`internalBlockToDeallocNSManagedObjectContext + 79
frame #17: 0x0259b014 libdispatch.dylib`_dispatch_client_callout + 14
frame #18: 0x0258b418 libdispatch.dylib`_dispatch_queue_drain + 239
frame #19: 0x0258b2a6 libdispatch.dylib`_dispatch_queue_invoke + 59
frame #20: 0x0258c280 libdispatch.dylib`_dispatch_root_queue_drain + 231
frame #21: 0x0258c450 libdispatch.dylib`_dispatch_worker_thread2 + 39
frame #22: 0x971cde12 libsystem_c.dylib`_pthread_wqthread + 441
答案 0 :(得分:4)
此问题并非特定于AFIncrementalStore的使用。我们在使用嵌套上下文和NSFetched结果控制器时遇到了同样的问题。
Child和Sibling上下文不需要使用相同的并发类型,不需要使用相同的线程。但是,您的获取结果控制器必须在其托管对象上下文使用的同一线程上使用,调试导航器中的线程2 NSManagedObjectContext队列使我认为这可能是一个线程问题。
如果这是你的主要背景,有时这就像包裹你的胎儿一样简单
dispatch_async(dispatch_get_main_queue(), ^{ [resultsController performFetch:nil]; });
或真正的偏执狂
[_resultsController.managedObjectContext performBlock:^{
[_resultsController performFetch:nil];
}];
答案 1 :(得分:2)
我无论如何都不是CoreData专家,所以请耐心等待。
您可能正在使用NSPrivateQueueConcurrencyType。 AFIncrementalStore似乎正在使用主队列进行同步。这是你的控制吗?
您可以尝试将NSManagedObjectContext切换为NSMainQueueConcurrencyType,看看是否有帮助吗?
现在,如果我是对的并且您正在使用NSPrivateQueueConcurrencyType,那么您可能出于性能原因而这样做。所以,这可能不是一个很好的长期解决方案......