existingObjectWithID deadlock with NSPrivateQueueConcurrencyType

孤街醉人 提交于 2019-12-04 08:33:05

You have shot yourself in the face.

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:).

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.

A great sadness ensues.


Edit: Thoughts on a possible solution

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.

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).

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!