关于多线程:嵌套在dispatch_get_main_queue内部的iOS dispatch_get_global_queue

iOS dispatch_get_global_queue nested inside dispatch_get_main_queue

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

1
2
3
4
5
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
dispatch_async(dispatch_get_main_queue(), dispatch_block_t block)

这会将block作为任务放在主队列(您的代码已经在其中运行)上,然后立即在其余方法中继续执行代码(如果他想等待block任务在继续之前完成,他会进行dispatch_sync调用)。
主队列是串行队列,因此它将完全按照以下顺序执行这些任务:

  • 在当前方法结束(当前任务的运行循环结束)之后继续执行block
  • 在将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

...那么发生的事情是什么顺序?

1
2
3
4
5
6
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标签的问题