让我们假设我有一个代码:
func someMethod() async {
... // processing 1
let someProperty = await someService.callSomeMethod()
... // processing 2
}
从WWDC中可以清楚地看出,在wait之前和之后执行的代码可以在不同的线程上执行。
但是,如果我想保证只有一个线程可以执行呢?
很明显,如果我们谈论的是强制上下文切换到主线程,那么用@MainActor属性指定方法就足够了,但假设我想将自己与特定线程隔离开来,那么someMethod中的所有内容都在一个上下文中执行对我来说很重要?(处理1和处理2具有相同的上下文)
Nutshell,在swift?
您不能真正保证关于线程的任何东西,除非只有一个主线程。无论何时await
,async/await机制都是完全自由的,可以在不同的线程上继续。
但这真的很低,你不应该在意。关键是,你可以通过将所有代码放在一个参与者中来保证串行行为。基本上,不同时运行一个方法两次的信号是使它成为一个参与者的方法。
(即使你的问题中的"隔离"一词也指向一个行动者。这就是行动者的含义,这是一种隔离机制。)
一个稍微复杂的问题是演员可以重新进入。这意味着,当actor方法说await
时,actor会在等待时打开自己以接受调用。这可能会变得一团糟。但这并不像让演员制造僵局那样混乱。
我强烈建议你阅读https://github.com/apple/swift-evolution/blob/main/proposals/0306-actors.md和https://github.com/apple/swift-evolution/blob/main/proposals/0313-actor-isolation-control.md.你第一次可能不会理解它们——我当然没有——但当我突然有了这个想法时,整个概念(演员、孤立、非孤立、重新进入、可发送)都立刻变得有意义了。