existingObjectWithID deadlock with NSPrivateQueueConcurrencyType [英] existingObjectWithID deadlock with NSPrivateQueueConcurrencyType
问题描述
我用 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 和
Link to Github project and open issue for some context into the issue.
推荐答案
你已经在脸上射杀了自己。
You have shot yourself in the face.
executeFetchRequest:error:
创建一个单独的子上下文,这个工作包括将工作同步分派到父队列(通过 insertOrUpdateObjects:
)。
executeFetchRequest:error:
creates a separate child context on which it does some work (while the parent's queue is blocked). This work involves synchronously dispatching work to the parent's queue (via insertOrUpdateObjects:
).
这是因为 NSManagedObjectContext
-existingObjectWithId:
使用嵌套上下文分派到父队列,以实现父上下文中出现的对象。很遗憾,您已经在子上下文中使用 performBlockAndWait
阻止父级的队列。
This is because NSManagedObjectContext
-existingObjectWithId:
with nested contexts dispatches to the parent's queue to fulfill objects faulted in to the parent context. Unfortunately you've already blocked the parent's queue with your performBlockAndWait
on the child context.
编辑:思考可能的解决方案
Thoughts on a possible solution
这里是由使用具有不同队列的嵌套上下文引起的。我不确定我理解在这种情况下使用嵌套上下文的动机,除非提供的上下文是NSMainQueueConcurrencyType。
The problem here is caused by the use of nested contexts with different queues. I'm not sure I understand the motivation for using a nested context in this situation unless the provided context is NSMainQueueConcurrencyType.
即使这样,强制fetch工作离开调用上下文的队列是危险的,因为如果fetch中的任何现有对象出现故障(如在此处所做的那样),则它们将成为此问题的牺牲品。
Even then, forcing fetch work off the calling context's queue is hazardous, since any existing objects in the fetch will fall victim to this problem if they are faulted (as is being done here).
有可能AFIncrementalStore保证在这种情况下的图隔离。我发现此问题针对AFNetwork存档:
It is possible that the AFIncrementalStore somehow guarantees graph isolation in this situation. I found this issue filed against AFNetwork:
https://github.com/AFNetworking/AFIncrementalStore/commit/1f822279e6a7096327ae56a2f65ce8e2ff36da83
这是可疑的相似之处在于,保留周期阻止对象被释放,从而导致它永久存在于父上下文中并且死锁试图故障。
It is suspiciously similar in that a retain cycle prevented an object from being deallocated, thereby causing it to permanently exist in the parent context and deadlock trying to fault.
这篇关于existingObjectWithID deadlock with NSPrivateQueueConcurrencyType的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!