2013-07-24 38 views
8

既然dispatch_get_current_queue在iOS 6中已被弃用,我该如何使用dispatch_after在当前队列中执行某些操作?如何在当前队列中dispatch_after?

+0

你需要保持在同一队列中,还是可以使用派遣到另一个队列(通过dispatch_get_global_queue或get_main_queue) –

+0

需要保持不变。 – Boon

+3

仅供参考,请参阅http:// stackoverflow。com/questions/13237417/alternatives-dispatch-get-current-queue-for-completion-blocks-in-ios-6,http://stackoverflow.com/questions/12842166/how-can-i-replace- deprecated-method-dispatch-get-current-queue-from-ios5-to-io,和http://stackoverflow.com/questions/12806506/how-can-i-verify-that-i-am-running-on -a-given-gcd-queue-without-using-dispatch-g进行关于此主题的相关讨论。 – Rob

回答

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中完成的,但我通常在应用程序代码中看到它,而且大多数情况下都是非常简单的方法。
+2

我对你的最后一条语句有些抱怨:如果这是一个回调(比如说完成,错误或进度处理程序),那么*主队列*应该是被选作默认执行上下文的最少候选者。使用主队列会增加死锁的概率。这是图书馆设计者的一个坏习惯,源自愚蠢和错误的假设,异步任务的客户想要在主线程上“做东西”。但是这使它变得更糟。 – CouchDeveloper

1

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

+0

我们假设我无法发送我的调用代码,说它来自静态库。 – Boon

+0

在这种情况下,会有一些间接的帮助吗?不要传递你想调用的代码,而要将你自己的代码包装到正确的队列中。 –

0

必须这样做可能是因为需要黑客。你可以解决这个破解另一个黑客:

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

相反usleep()的你可能会考虑到循环的运行循环。

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

而且,顺便说一下,有办法在一个块执行,以检查它是否运行在特定队列 - 分别在任何队列的,只要你有该队列事先参考:使用功能dispatch_queue_set_specificdispatch_get_specific

相关问题