当前位置: 首页 > news >正文

Swift 新 async/await 同步机制小技巧:消除“多余”的 await 关键字

在这里插入图片描述

概览

在使用多个Actor 共同实现同步功能的时候,我们往往会看到如下使用场景:

Actor A 必须在主线程上运行,Actor B可以在任意线程上运行,但需要适时的调用 Actor A 中的方法。

在这种情况下,我们会遇到如下代码:

在这里插入图片描述

如上代码所示,需要在 worker.doing() 调用前加上 await 关键字,毕竟此时可能会发生任务挂起和切换。

其实,我们还有一种更好的方法来完成 working.doing() 方法的调用,下面就让我们来看看如何操作吧。 😉


代码解析

示例的源代码如下,非常简单:

@MainActor
class Worker {
    func doing() {
        print("important working...")
    }
}

actor Superman {
    unowned let worker: Worker!
    
    init(worker: Worker) {
        self.worker = worker
    }
    
    func todo() {
        Task {
            await worker.doing()
        }
    }
}

我们看到 Worker 类必须在主线程上保持同步,而 Superman 可以在任意线程上进行同步,但需要调用 Worker 中的 doing() 方法。

除了使用 await 关键字修饰 worker.doing() 方法之外,我们还可以显式让 Swift 明白我们的 Task 闭包代码必须在主线程上执行。

解决之道

在 Swift 推出新 async/await 并发模型的同时,Apple 同样对闭包调用做了升级。

现在,我们可以在闭包中添加新的 @MainActor 关键字来明确闭包内容必须在主线程上运行。

于是乎,上面的代码就可以修改为如下形式:

actor Superman {
    unowned let worker: Worker!
    
    init(worker: Worker) {
        self.worker = worker
    }
    
    func todo() {
        Task { @MainActor in
            worker.doing()
        }
    }
}

我们成功的“摆脱”了 await 关键字,并且让意图更加明显。

总结

其实,我们并没有真正摆脱 await 关键字,任务切换仍然会和原来一样发生,只不过我们不再关心,只要看到闭包中的 @MainActor 关键字,一切都了然了,不是吗?

感谢观赏,再会 ! 😃

相关文章:

  • Github如何使用详细介绍(保姆级教学)
  • 【ardunio+sx1268】与【esp32+sx1268】实现不同主控单片机lora通讯
  • Linux常用命令——pvscan命令
  • Openharmony的编译构建--进阶篇1
  • 【C++入门】缺省参数
  • 【34】C语言 | 动态内存管理
  • QT入门Buttons之QToolButton
  • 小程序开发常见问题总结(超实用)
  • LCX端⼝转发
  • 数据分析:SQL和Python
  • 蓝桥杯重点(C/C++)(随时更新,更新时间:2023.1.31)
  • 本地Exchange备份方案
  • linux安装docker
  • 【K8S系列】Pod重启策略及重启可能原因
  • 【Linux】冯诺依曼体系结构
  • vue使用echarts画可视化大屏
  • docker 高级篇
  • 【进击的算法】动态规划——01背包
  • 实验8-动态规划与背包问题
  • docker安装mongdb