为啥在 swift 的 mac 命令行工具中使用 DispatchQueue.main.async 时需要运行循环?

Posted

技术标签:

【中文标题】为啥在 swift 的 mac 命令行工具中使用 DispatchQueue.main.async 时需要运行循环?【英文标题】:Why run loop is needed when using DispatchQueue.main.async in mac command line tool in swift?为什么在 swift 的 mac 命令行工具中使用 DispatchQueue.main.async 时需要运行循环? 【发布时间】:2020-08-15 11:44:33 【问题描述】:

我找到了 Apple 的文档来理解为什么我应该使用运行循环来实现主调度队列中的任务。

根据Apple docs,

主调度队列是一个全局可用的串行队列,它在应用程序的主线程上执行任务。 此队列与应用程序的运行循环一起使用(如果存在),将排队任务的执行与附加到运行循环的其他事件源的执行交错​​。因为它在应用程序的主线程上运行,所以主队列通常用作应用程序的关键同步点。

但是,我仍然无法理解“为什么”需要运行循环。听起来像是“它需要运行循环,因为它需要运行循环”。如果有人向我解释这一点,我将不胜感激。谢谢。

【问题讨论】:

***.com/questions/9449123/… 就是一个很好的例子 【参考方案1】:

为什么我应该使用运行循环来实现主调度队列中的任务

通常情况下,您不需要,因为您已经在使用一个!

在一个应用程序项目中,有一个主队列运行循环已经。例如,一个 ios 应用项目实际上只是对 UIApplicationMain 的一次巨大调用,它提供了一个运行循环。

这就是它能够坐在那里等待用户做某事的方式。运行循环正在运行。并循环播放。

但在 Mac 命令行工具中,没有自动运行循环。它运行它的主要功能并立即退出。如果您需要它不这样做,您将提供一个运行循环。

【讨论】:

【参考方案2】:

DispatchQueue.main.async 是你有代码的时候 在后台队列上运行,您需要特定的代码块 在主队列上执行。

在您的代码中,viewDidLoad 已经在主队列上运行,所以 几乎没有理由使用 DispatchQueue.main.async。

但使用它不一定是错误的。但它确实改变了顺序 执行。

异步闭包在当前运行循环完成后排队运行。

【讨论】:

【参考方案3】:

我不明白“为什么”需要运行循环

通常,命令行应用程序不需要运行循环。如果您有特殊需求(例如,您有一些动态 UI 在等待用户输入时执行某些任务),您可以使用运行循环,但绝大多数命令行应用程序不需要运行循环。

正如the docs 所说:

运行循环是一个事件处理循环,用于安排工作和协调接收传入事件。运行循环的目的是在有工作要做的时候让你的线程保持忙碌,而在没有工作的时候让你的线程进入睡眠状态。

因此,如果您需要让您的应用等待一些传入事件,或者您在队列之间异步调度任务,那么可以使用运行循环,否则,请不要打扰。大多数命令行应用根本不需要使用运行循环。

【讨论】:

以上是关于为啥在 swift 的 mac 命令行工具中使用 DispatchQueue.main.async 时需要运行循环?的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中使用命令行工具更新当前行

如何在Mac上安装命令行工具?

pathForResource 在 Mac OS X 控制台应用程序中返回 nil — Swift

Swift 代码在 Playground 中有效,但在命令行工具中无效

如何使用命令行工具为 Mac OS X 创建漂亮的 DMG?

Mac OS Gatekeeper 阻止签名命令行工具