我继承了使用以下结构进行线程化的代码库:
dispatch_async(dispatch_get_main_queue(), { () -> Void in
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), { () -> Void in
//Several AFNetworking Server calls...
})
})
我对线程不是很有经验,所以我试图找出这个结构背后的可能意图。为什么只抓住主队列才能立即访问另一个队列?这是一种常见做法吗?对于更多上下文,此代码在UIApplicationDidBecomeActiveNotification
通知中执行,进行几次必要的服务调用。
这种结构安全吗?基本上我的目标是在不阻止UI的情况下进行服务调用。任何帮助或意见都表示赞赏。
答案 0 :(得分:2)
所以我认为这是一个有人决定写的有趣的几行,所以让我们分解这里发生的事情(我可能会把事情搞得太多,提前抱歉,这只是帮助我自己的思路)
dispatch_async(dispatch_get_main_queue(), dispatch_block_t block)
这会将block
作为一个任务放在主队列(代码已在其中运行)上,然后立即继续执行该方法的其余部分的代码(如果他想等待在继续之前完成的block
任务,他已经拨打了dispatch_sync
电话。)
主队列是串行的,因此它将按以下顺序执行这些任务:
block
(当前任务的运行循环结束)dispatch_async
block
任务进入队列之前执行可能已异步添加到主队列的任何其他任务block
任务现在block
只将另一个任务调度到高优先级全局队列。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), block2)
DISPATCH_QUEUE_PRIORITY_HIGH
是并发队列 - 因此,如果您要将多个任务分派到此队列,则可能会并行执行这些任务,具体取决于多个系统因素。
您的老同事希望确保block2
中的网络电话尽快完成
因为block
正在调用dispatch_async
(立即返回),block
任务完成,允许主队列执行队列中的下一个任务。
到目前为止的最终结果是block2
排队进入高优先级全局队列。执行完毕后,网络调用完成后,将调用回调方法和yadayada
......那么发生的事情的顺序是什么?
dispatch_async(dispatch_get_main_queue(), { () -> Void in
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), { () -> Void in
//Several AFNetworking Server calls...
})
})
//moreCode
1)moreCode执行
2)block
执行(将block2
与网络调用添加到全局队列中)
3/4)主队列中的下一个任务执行
4/3)全局队列中的网络任务执行
首先发生的顺序可能在3到4之间变化,但是你的并发性是这样的:)
因此,除非老同事希望在添加之前先执行moreCode
网络调用全局队列,否则您可以继续将该初始dispatch_async
删除到主队列中。
假设看起来他们希望尽快完成网络调用,那么可能没有理由将这些网络任务添加到全局队列中。
打开任何输入^^。我的经验包括今天阅读有关GCD的所有文档,然后决定查看一些GCD标记的问题