I'm trying to understand a design pattern for accessing the isolated state held in an actor type from within a SwiftUI view.
Take this naive code:
actor Model: ObservableObject {
@Published var num: Int = 0
func updateNumber(_ newNum: Int) {
self.num = newNum
}
}
struct ContentView: View {
@StateObject var model = Model()
var body: some View {
Text("\(model.num)") // <-- Compiler error: Actor-isolated property 'num' can not be referenced from the main actor
Button("Update number") {
Task.detached() {
await model.updateNumber(1)
}
}
}
}
Understandably I get the compiler error Actor-isolated property 'num' can not be referenced from the main actor
when I try and access the isolated value. Yet I can't understand how to display this data in a view.
The accepted answer might not suite all use cases.
In my case, I want the ObservableObject
to remain an actor
, but access one of its property from a SwiftUI view. So I added @MainActor
only to that property.
This means that property also needs to be updated only from the main thread as shown below.
actor Model: ObservableObject {
@MainActor @Published var num: Int = 0
func updateNumber(_ newNum: Int) {
Task { @MainActor in
self.num = newNum
}
}
// all other properties and functions will remain isolated to the actor
}