我在Swift中尝试新的异步/等待模式,我遇到了一些东西,我发现它令人困惑。
struct ContentView: View {
var body: some View {
Text("Hello World!")
.task {
var num = 1
Task {
print(num)
}
Task {
print(num)
}
}
}
func printScore() async {
var score = 1
Task { print(score) }
Task { print(score) }
}
}
有人能解释一下为什么编译器只抱怨在printScore()
函数中捕获了var
,而在ContentView
结构体的body
计算属性上使用task
修饰符执行相同操作时却没有抱怨(即第14-24行)?
这是我想到的一个例子,我对编译器的行为感到困惑。我还将编译器设置“严格并发检查”的构建设置更改为“完成”,但仍然没有看到编译器抱怨。
1条答案
按热度按时间mzsu5hc01#
这是
@MainActor
的一个特殊功能。在视图中,body
被标记为MainActor:任务继承其调用者的上下文,因此这些任务也是MainActor。如果在
body
中将Task
替换为Task.detached
,您将看到相同的错误,因为这会将任务移出MainActor上下文。相反,如果您将
@MainActor
添加到printScore
,它也将编译无误:score
继承了MainActor指定,并且受到保护。没有对score
的并发访问,因此这是正确的。这实际上适用于所有参与者,但我认为编译器有一个bug,它使事情不像你期望的那样运行。
但是,如果删除对
actorVar
的引用,传递给Task的闭包将不会放入参与者的上下文中,这将使对localVar
的引用无效。