如何在当前队列中调度_after?

时间:2013-07-24 16:32:07

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

现在在iOS 6中不推荐使用dispatch_get_current_queue,如何使用dispatch_after在当前队列中执行某些操作?

3 个答案:

答案 0 :(得分:5)

评论中的各种链接并未说“最好不要这样做”。他们说你不能这样做。您必须传递所需的队列或分派到已知队列。调度队列没有“当前”的概念。块通常从一个队列馈送到另一个队列(称为“定位”)。当你实际运行时,“当前”队列并没有真正意义,依靠它可以(并且历史上确实)导致死锁。 dispatch_get_current_queue()从未打算用于派遣;这是一种调试方法。这就是为什么它被删除了(因为人们把它视为有意义的东西)。

如果您需要这种更高级别的簿记,请使用跟踪其原始队列的NSOperationQueue(并且有一个更简单的排队模型,使“原始队列”更有意义)。

UIKit中使用的几种方法是合适的:

  • 将回调dispatch_queue作为参数传递(这可能是新API中最常用的方法)。有关示例,请参阅[NSURLConnection setDelegateQueue:]addObserverForName:object:queue:usingBlock:。请注意,NSURLConnection需要NSOperationQueue,而不是dispatch_queue。更高级别的API以及所有这些。
  • 回拨您正在使用的任何队列,并将其留给接收方处理。这就是回调传统上的工作方式。
  • 要求调用线程上有runloop,并在调用runloop上安排回调。这就是NSURLConnection在队列之前的历史工作方式。
  • 除非另有说明,否则请始终在其中一个众所周知的队列(尤其是主队列)上进行回调。我不知道在UIKit中这是做什么的,但我在应用程序代码中经常看到它,并且在大多数情况下是一种非常简单的方法。

答案 1 :(得分:1)

手动创建一个队列,并将您的调用代码和dispatch_after代码分发到该代码上。这样,您就可以保证两段代码都从同一队列运行。

答案 2 :(得分:0)

必须这样做可能是因为需要黑客攻击。你可以通过另一个黑客来解决这个问题:

id block = ^foo() {
    [self doSomething];
    usleep(delay_in_us);  
    [self doSomehingOther];
}

而不是usleep(),您可以考虑在循环中循环。

我不会推荐这种“方法”。更好的方法是使用一些方法将队列作为参数,将块作为参数,然后在指定的队列上执行该块。

顺便说一句,在块执行期间有一些方法可以检查它是否在特定队列上运行 - 分别在其任何队列上运行,前提是你事先引用该队列:使用函数dispatch_queue_set_specificdispatch_get_specific