我正在使用NSPrivateQueueConcurrencyType
并发类型而不是NSMainQueueConcurrencyType
进行冻结(死锁?)。
我的上下文初始化:
_managedObjectContext = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
麻烦的代码:
NSManagedObjectID *managedObjectID = [self managedObjectIDForEntity:entity
withParseObjectId:object.objectId];
managedObject = [context existingObjectWithID:managedObjectID error:error];
回溯:
链接到Github project和open issue以了解该问题的某些背景信息。
答案 0 :(得分:4)
你已经开枪了。
executeFetchRequest:error:
创建一个单独的子上下文,它可以在其上执行某些工作(而父队的队列被阻止)。这项工作涉及将工作同步分派到父队列(通过insertOrUpdateObjects:
)。
这是因为具有嵌套上下文的NSManagedObjectContext
-existingObjectWithId:
会调度到父队列,以完成故障到父上下文的对象。很遗憾,您已经在子级上下文中使用performBlockAndWait
阻止了父级队列。
随之而来的是悲伤。
编辑:关于可能的解决方案的想法
这里的问题是由使用具有不同队列的嵌套上下文引起的。我不确定在这种情况下我是否理解使用嵌套上下文的动机,除非提供的上下文是NSMainQueueConcurrencyType。
即使这样,强制取消调用上下文队列的工作也是危险的,因为如果它们出现故障(如此处所述),则fetch中的任何现有对象都将成为此问题的牺牲品。
在这种情况下,AFIncrementalStore可能会以某种方式保证图形隔离。我发现这个问题是针对AFNetwork提出的:
https://github.com/AFNetworking/AFIncrementalStore/commit/1f822279e6a7096327ae56a2f65ce8e2ff36da83
可疑的是,保留周期阻止了对象被解除分配,从而导致它永久存在于父上下文中并且死锁试图发生故障。