GCD已弃用方法

时间:2013-07-18 10:27:03

标签: ios objective-c grand-central-dispatch

我曾经有一个帮助方法(静态),确保在正确的队列上调用完成块。

  + (void)_deadlockCheckBlock:(void(^)(void))block caller:(dispatch_queue_t)caller {
     NSParameterAssert(block);
     NSParameterAssert(caller);
     if (caller == dispatch_get_current_queue()) {
        block();
     }
     else {
        dispatch_async(caller, block);
     }}

现在克服

的弃用
dispatch_get_current_queue()

我使用get_main_queue方法重写了该方法。

+ (void)_deadlockCheckBlock:(void(^)(void))block caller:(dispatch_queue_t)caller {
   NSParameterAssert(block);
   NSParameterAssert(caller);
   dispatch_sync(dispatch_get_main_queue(), ^{
     //This will ensure to be on the main queue
     if (caller == dispatch_get_main_queue()) {
        block();
     }
     else {
        dispatch_async(caller, block);
     }
   });}

是否有更好的方法可以在不进入主队列的情况下获得相同的行为?

1 个答案:

答案 0 :(得分:3)

问题(以及不推荐使用get_current_queue的原因)是可以有许多当前队列。如果你将dispatch_sync从一个队列调度到另一个队列,那么两者现在都是“当前的”,因为dispatch_sync对其中任何一个都会死锁。与dispatch_set_target_queue相同。

避免死锁的可靠方法是始终使用dispatch_async(或其他异步API;例如dispatch_group_notify),以避免重入控制流,或传递足够的其他信息以正确决定(如果使用队列作为锁定,则可能有一个“已经锁定”的标志,例如你传递的。)

通常,需要递归锁定的代码或模拟它们的东西(比如使用当前队列决定是否调度dispync)是可能有一些不变量(锁定保护的那个)被破坏的代码,并且预计无论如何都会工作,这是一个有点可怕的概念。