iOS 6中完成块的dispatch_get_current_queue()的替代方法?

我有一个方法,接受一个块和一个完成块。 第一个块应该在后台运行,而完成块应该在该方法被调用的任何队列中运行。

对于后者,我总是使用dispatch_get_current_queue() ,但似乎在iOS 6或更高版本中已被弃用。 我应该用什么来代替?

“打在呼叫者的任何队列上”的模式是吸引人的,但最终不是一个好主意。 该队列可以是低优先级队列,主队列或具有奇怪属性的其他队列。

我最喜欢的方法是说“完成块运行在具有以下属性的实现定义的队列上:x,y,z”,如果调用者想要更多的控制,则让块调度到特定的队列。 要指定的一组典型属性就像“串行,不可重入,以及相对于任何其他应用程序可见队列的asynchronous”。

**编辑**

鲶鱼人在下面的评论中举了一个例子,我只是把它添加到他的答案。

 - (void) aMethodWithCompletionBlock:(dispatch_block_t)completionHandler { dispatch_async(self.workQueue, ^{ [self doSomeWork]; dispatch_async(self.callbackQueue, completionHandler); } } 

这对于您所描述的API来说基本上是错误的。 如果一个API接受一个块和一个完成块来运行,以下事实需要是正确的:

  1. “要运行的块”应该在内部队列上运行,例如对于API是私有的队列,因此完全在该API的控制之下。 唯一的例外是,如果API特别声明块将在主队列或全局并发队列之一上运行。

  2. 完成块应始终表示为一个元组(队列,块),除非与#1的假设相同,例如完成块将在已知的全局队列上运行。 此外,应该在传入的队列中调度asynchronous。

这些不只是风格点,如果你的API是安全的,从死锁或其他边缘情况的行为,否则将是完全必要的,否则将有一天你会离开最近的树。 🙂

其他答案很好,但对我来说答案是结构性的。 我有一个这样的单身人士的方法:

 - (void) dispatchOnHighPriorityNonMainQueue:(simplest_block)block forceAsync:(BOOL)forceAsync { if (forceAsync || [NSThread isMainThread]) dispatch_async_on_high_priority_queue(block); else block(); } 

它有两个依赖关系,它们是:

 static void dispatch_async_on_high_priority_queue(dispatch_block_t block) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), block); } 

 typedef void (^simplest_block)(void); // also could use dispatch_block_t 

这样我集中我的电话派遣在另一个线程。

你首先应该小心使用dispatch_get_current_queue 。 从头文件:

build议仅用于debugging和logging目的:

代码不能对返回的队列做任何假设,除非它是全局队列或代码本身创build的队列之一。 如果该队列不是由dispatch_get_current_queue()返回的队列,则代码不能假定队列上的同步执行是安全的。

你可以做任何一件事情:

  1. 保留一个对你最初发布的队列的引用(如果你是通过dispatch_queue_create创build的),然后使用它。

  2. 通过dispatch_get_global_queue使用系统定义的队列,并跟踪你正在使用哪一个队列。

有效地,而以前依靠系统来跟踪你正在排队,你将不得不自己做。

对于那些仍然需要队列比较的人来说,你可以通过他们的标签来比较队列或者指定队列。 检查这个https://stackoverflow.com/a/23220741/1531141

苹果已经弃用dispatch_get_current_queue() ,但在其他地方留下了一个漏洞,所以我们仍然能够得到当前的调度队列:

 if let currentDispatch = OperationQueue.current?.underlyingQueue { print(currentDispatch) // Do stuff } 

这至less适用于主队列。 请注意,这个underlyingQueue属性自iOS 8开始可用。

如果你需要在原队列中执行完成块,你也可以直接使用OperationQueue ,我的意思是没有GCD。