somu
(somu)
July 23, 2022, 10:10am
1
Note:
This is not a SwiftUI question, I was more concerned about the error thrown.
Overview:
I am encountering the error Converting function value of type '@MainActor () -> ()' to '() -> Void' loses global actor 'MainActor'
Questions:
Is this a bug in the SwiftUI API not accepting main actor closure or am I missing something?
Is there a way to resolve the issue without having to place the contents of buttonAction
inside the action closure (as shown in the second button)?
Environment
Build Setting: Strict Concurrency Checking > Complete
Xcode: Version 14.0 beta 3 (14A5270f)
macOS: 13.0 Beta (22A5295i)
Code:
@MainActor
class Model: ObservableObject {
func f1() {}
}
struct ContentView: View {
@StateObject private var model = Model()
var body: some View {
VStack {
//Error: Converting function value of type '@MainActor () -> ()' to '() -> Void' loses global actor 'MainActor'
Button(action: buttonAction) {
Text("Tap me")
}
//Compiles fine
Button {
buttonAction()
} label: {
Text("Tap me")
}
}
}
func buttonAction() {
model.f1()
}
}
4 Likes
somu
(somu)
July 25, 2022, 4:28am
2
Submitted feedback FB10859400
tera
July 25, 2022, 9:04am
3
What happens for this version?
Button(action: model.f1) {
Text("Tap me")
}
somu
(somu)
July 25, 2022, 9:19am
4
Thanks @tera , the same error is thrown even for your code as well.
This happens only when the build setting Strict Concurrency Checking
is set as Complete
.
Based on Eliminate data races using Swift Concurrency - WWDC22 - Videos - Apple Developer (24:41 min) the build setting is mentioned.
audulus
(Taylor Holliday)
May 28, 2023, 4:31pm
5
Why does wrapping in another function fix the warning?
I'm seeing these warnings with Strict Concurrency Checking
set to Minimal
(and in Swift Packages).
1 Like
danniss10
(Daniel Nissenbaum)
July 19, 2023, 2:20pm
6
I've been seeing this issue as a warning with complete concurrency checking. The warning is pretty pervasive in SwiftUI Buttons. I think that SwiftUI needs to annotate the action parameter of the button initializer with @MainActor .
Filed FB12575405
5 Likes
JetForMe
(Rick M)
January 27, 2024, 2:55am
8
I don't understand this, either. I filed FB13562256.
hborla
(Holly Borla)
January 27, 2024, 4:17am
9
somu:
Is this a bug in the SwiftUI API not accepting main actor closure or am I missing something?
Is there a way to resolve the issue without having to place the contents of buttonAction
inside the action closure (as shown in the second button)?
Even though Button.init
does not take a @MainActor
closure for the action
parameter, the type of the closure is not Sendable
and it's formed on the main actor (because body
is @MainActor
isolated), so it cannot escape the main actor. There's no potential for data races here.
This issue was resolved by [Concurrency] Do not allow actor isolation violations in function conversions to impact constraint solving. by hborla · Pull Request #68685 · apple/swift · GitHub which eliminated a bunch of false positives in the loss-of-global-actor function conversion diagnostics, and the fix is included in Swift 5.10.
3 Likes
somu
(somu)
January 27, 2024, 5:34am
10
Thanks a lot @hborla great to hear that is fixed in Swift 5.10, hopefully that would reduce a lot of the warnings helping to focus on the real warnings / issues.
msadoon
(Mubarak Sadoon)
March 30, 2024, 3:55pm
11
Still seeing this in Xcode 15.3 Swift 5.10
Button(action: addListTodo) {
Label("", systemImage: EnvironmentVars.Buttons.addNote)
}
@MainActor
private func addListTodo() {
let createDataHandler = createDataHandler
Task.detached {
...
}
}