cfi*_*her 98 cocoa-touch objective-c grand-central-dispatch objective-c-blocks ios6
我有一个接受块和完成块的方法.第一个块应该在后台运行,而完成块应该在调用方法的任何队列中运行.
对于后者我总是使用dispatch_get_current_queue()
,但似乎它在iOS 6或更高版本中已被弃用.我应该用什么呢?
Cat*_*Man 63
"在呼叫者所在的任何队列上运行"的模式很有吸引力,但最终并不是一个好主意.该队列可以是低优先级队列,主队列或具有奇数属性的其他队列.
我最喜欢的方法是说"完成块在具有以下属性的实现定义队列上运行:x,y,z",并且如果调用者想要更多控制,则让块调度到特定队列.要指定的一组典型属性类似于"串行,非重入和相对于任何其他应用程序可见队列的异步".
**编辑**
Catfish_Man在下面的评论中举了一个例子,我只是将它添加到他的答案中.
- (void) aMethodWithCompletionBlock:(dispatch_block_t)completionHandler
{
dispatch_async(self.workQueue, ^{
[self doSomeWork];
dispatch_async(self.callbackQueue, completionHandler);
}
}
Run Code Online (Sandbox Code Playgroud)
jkh*_*jkh 25
这基本上是您要描述的API的错误方法.如果API接受要运行的块和完成块,则需要满足以下事实:
"要运行的块"应该在内部队列上运行,例如一个私有的API队列,因此完全在该API的控制下.唯一的例外是,如果API明确声明该块将在主队列或其中一个全局并发队列上运行.
除非与#1相同的假设成立,否则完成块应始终表示为元组(队列,块),例如,完成块将在已知的全局队列上运行.此外,还应在传入队列中调度完成块async.
这些不仅仅是风格上的点,如果您的API要安全,不受死锁或其他边缘情况的影响,它们将是完全必要的,否则有一天会让您从最近的树上挂起来.:-)
Dan*_*ark 14
其他答案很棒,但对我来说,答案是结构性的.我有一个像Singleton这样的方法:
- (void) dispatchOnHighPriorityNonMainQueue:(simplest_block)block forceAsync:(BOOL)forceAsync {
if (forceAsync || [NSThread isMainThread])
dispatch_async_on_high_priority_queue(block);
else
block();
}
Run Code Online (Sandbox Code Playgroud)
它有两个依赖关系,它们是:
static void dispatch_async_on_high_priority_queue(dispatch_block_t block) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), block);
}
Run Code Online (Sandbox Code Playgroud)
和
typedef void (^simplest_block)(void); // also could use dispatch_block_t
Run Code Online (Sandbox Code Playgroud)
这样我就可以将我的调用集中在另一个线程上.
WDU*_*DUK 12
你应该首先注意你的使用dispatch_get_current_queue
.从头文件:
建议仅用于调试和记录目的:
代码不得对返回的队列做任何假设,除非它是全局队列之一或代码本身创建的队列.如果该队列不是dispatch_get_current_queue()返回的队列,则代码不得假设同步执行到队列是安全的死锁.
你可以做以下两件事之一:
保留对最初发布的队列的引用(如果您是通过它创建的dispatch_queue_create
),并从那时开始使用它.
使用系统定义的队列dispatch_get_global_queue
,并跟踪您正在使用的队列.
在以前依靠系统跟踪您所在的队列的同时,您将不得不自己完成.
Apple 已经弃用了dispatch_get_current_queue()
,但在其他地方留下了一个漏洞,所以我们仍然能够获得当前的调度队列:
if let currentDispatch = OperationQueue.current?.underlyingQueue {
print(currentDispatch)
// Do stuff
}
Run Code Online (Sandbox Code Playgroud)
这至少适用于主队列。请注意,该underlyingQueue
属性自 iOS 8 起可用。
如果你需要在原队列中执行完成块,你也可以OperationQueue
直接使用,我的意思是没有GCD。
归档时间: |
|
查看次数: |
50003 次 |
最近记录: |