iOS dispatch_get_global_queue嵌套在dispatch_get_main_queue中

时间:2015-08-30 02:34:06

标签: ios multithreading grand-central-dispatch

我继承了使用以下结构进行线程化的代码库:

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的情况下进行服务调用。任何帮助或意见都表示赞赏。

1 个答案:

答案 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标记的问题