AKI*_*MAR 4 ios async-await swift swiftui swift-concurrency
我正在快速尝试新的异步/等待模式,但遇到了一些让我感到困惑的事情。
\nstruct ContentView: View {\n var body: some View {\n Text("Hello World!")\n .task {\n var num = 1\n\n Task {\n print(num)\n }\n\n Task {\n print(num)\n }\n }\n }\n\n func printScore() async {\n var score = 1\n\n Task { print(score) }\n Task { print(score) }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n有人可以澄清一下上面的屏幕截图,为什么编译器只抱怨捕获的var内部函数,而在使用结构体的计算属性上的修饰符printScore() 执行相同操作时不抱怨(即第 14-24 行)?taskbodyContentView
这是我提出的示例,并对编译器行为感到困惑。我还将编译器设置“严格并发检查\xe2\x80\x9d 构建设置”更改为\xe2\x80\x9cComplete\xe2\x80\x9d,但仍然不这样做没有看到编译器抱怨。
\n这是一种特殊的力量@MainActor。在视图中,body被标记为 MainActor:
@ViewBuilder @MainActor var body: Self.Body { get }
Run Code Online (Sandbox Code Playgroud)
任务继承其调用者的上下文,因此它们也是 MainActor。如果替换Task为Task.detachedin body,您将看到相同的错误,因为这会将任务移出 MainActor 上下文。
相反,如果添加@MainActor它printScore也将编译无错误:
@MainActor func printScore() async {
var score = 1
Task { print(score) }
Task { print(score) }
}
Run Code Online (Sandbox Code Playgroud)
score继承 MainActor 名称并受到保护。没有并发访问score,因此这是正确的。
这实际上适用于所有参与者,但我相信编译器有一个错误,使事情的行为不太符合您的预期。以下代码编译:
actor A {
var actorVar = 1
func capture() {
var localVar = 1
Task {
print(actorVar)
print(localVar)
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果删除对 的引用actorVar,则传递给 Task 的闭包将不会放入参与者的上下文中,这将使引用localVar无效。IMO,这是一个编译器错误。
| 归档时间: |
|
| 查看次数: |
1451 次 |
| 最近记录: |