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接受一个块和一个完成块来运行,以下事实需要是正确的:
-
“要运行的块”应该在内部队列上运行,例如对于API是私有的队列,因此完全在该API的控制之下。 唯一的例外是,如果API特别声明块将在主队列或全局并发队列之一上运行。
-
完成块应始终表示为一个元组(队列,块),除非与#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()返回的队列,则代码不能假定队列上的同步执行是安全的。
你可以做任何一件事情:
-
保留一个对你最初发布的队列的引用(如果你是通过
dispatch_queue_create
创build的),然后使用它。 -
通过
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。