I noticed this when playing around with concurrency in Xcode 14. When using task
in a view builder is allows me to call methods annotated with @MainActor
but I can't figure out why. In attempt to see if it had something to do with the way task
is defined as a method I tried to copy it's signature in my own method but it doesn't behave the same way.
@MainActor
func foo() {
print("Hey!")
}
extension View {
@inlinable func flask(priority: TaskPriority = .userInitiated, _ action: @escaping @Sendable () async -> Void) -> some View {
return self
}
}
struct ContentView: View {
var body: some View {
Text("Hello, world!")
.task {
foo()
}
.flask {
foo() // <-- Error: Expression is 'async' but is not marked with 'await'
}
}
}
I was expecting task
to execute on a background thread given that you can pass a priority as it's first argument, but when I set a break point within the closure, it's indeed on the main thread. I guess for some reason it's adopting the @MainActor
from body
, and maybe the the priority is applied to async methods called within the task but not the task
method itself.
How does this work?