Hi, I can confirm your SwiftUI example result. Also, enbaling strict concurrency check doesn't help in this case (no error or warning message on the silent ignorance of @MainActor
). Based on the explanation here, I modified the code by removing async
from all closure signatures. With that change, my experiment showed they all ran in main thread.
However, what I really want to say is that IMO your code are unnecessarily complex - @MainActor
and async
keywords show up in too many places, which is not only inefficient but also hard to reason about. Take the first part of the code an example, below is how I'd implement it (note that only run()
is async
and has @MainActor
applied). Hope it helps.
struct RunActionView: View {
let title: String
let action: () -> Void
init(title: String, action: @escaping () -> Void) {
self.title = title
self.action = action
}
var body: some View {
Button(action: executeAction) {
Text(title)
}
}
private func executeAction() {
print(title)
Task {
try await run(operation: action)
}
}
}
@MainActor
func run(operation: () throws -> Void) async throws {
try operation()
}