8

现在dispatch_get_current_queue在 iOS 6 中已弃用,我如何使用dispatch_after在当前队列中执行某些内容?

4

3 回答 3

5

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

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

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

  • 将回调 dispatch_queue 作为参数传递(这可能是新 API 中最常见的方法)。有关示例,请参见[NSURLConnection setDelegateQueue:]addObserverForName:object:queue:usingBlock:。请注意,NSURLConnection期望的是NSOperationQueue,而不是dispatch_queue。更高级别的 API 等等。
  • 回调您所在的任何队列并将其留给接收者处理。这就是传统上回调的工作方式。
  • 要求调用线程上有一个runloop,并在调用runloop上安排你的回调。这就是NSURLConnection排队之前的历史工作方式。
  • 除非另有说明,否则请始终在知名队列之一(尤其是主队列)上进行回调。我不知道这是在 UIKit 中完成的,但我在应用程序代码中经常看到它,并且大多数时候是一种非常简单的方法。
于 2013-08-01T19:08:02.337 回答
1

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

于 2013-07-30T21:30:16.077 回答
0

不得不这样做很可能是因为需要破解。你可以用另一个 hack 来解决这个问题:

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

而不是usleep()您可能会考虑在运行循环中循环。

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

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

于 2013-08-01T18:30:25.807 回答