《Effective Objective-C 2.0》中“第46条:不要使用dispatch_get_current_queue”笔记
我们都知道,在串行队列的同步任务中,再次向其中派发同步任务会造成死锁(向主队列派发同步任务的死锁就是这样)。但是,如果是下面这样呢?
|
|
结果同样死锁。这是因为最内部派发到queueA中的任务需要按队列的方式,等待先入队的最外层任务执行完成,但最外层任务被最内部的任务阻塞无法继续执行,故导致死锁。这在道理上与最简单的死锁没有区别。
但是,当我们想要使用dispatch_get_current_queue函数,对内部执行队列进行区分,防止死锁时,可以发现此方法早已被标记为了deprecated。也就是说,此函数返回的队列不能作为任务执行队列的判断依据。
故数组建议我们使用dispatch_queue_set_specific函数,对队列绑定相关数据。在派发的任务执行时,动态取出绑定数据来判定当前的执行队列。
直接看对比示例:
|
|
执行结果:
LockTest[19151:825723] currentQueue == queueB
LockTest[19151:825723] in queueA
LockTest[19151:825723] hahahahaha~~
LockTest[19151:825723] finish!!!!
可以看出,由于设置了目标队列,实际上是有queueA执行派发任务。但是dispatch_get_current_queue只能反映出原始派发任务的队列,而通过dispatch_get_specific函数取到的绑定数据却是根据真实执行任务的队列获取到。故在同步派发任务时,为了防止死锁,可以使用dispatch_queue_set_specific和dispatch_get_specific配对,来识别当前执行任务的队列。
这就是不要使用dispatch_get_current_queue的原因。