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 {
...
}
}
somu
(somu)
August 4, 2024, 1:43pm
12
The original code compiles fine in Xcode 16.0 beta 4 (16A5211f) for iOS 18 and macOS 15
Note: In iOS 18 and macOS 15, View is @MainActor struct