Given:
@MainActor
class UserSettings {
var isFeatureEnabled = false
}
It is really incongruous to me that, given the code above, I can get the value of isFeatureEnabled
from a non-main-actor context, but I cannot set the value:
// fine:
let isFeatureEnabled = await settings.isFeatureEnabled
// very not fine:
await settings.isFeatureEnabled = true
There are three main ways to work around this:
Make a method
extension UserSettings {
func setIsFeatureEnabled(_ bool: Bool) { self.isFeatureEnabled = bool }
}
This feels like unnecessary ceremony and is prone to typographical naming errors and leads to inconsistencies in that sometimes I can do .isFeatureEnabled = value
and sometimes I must use the method.
Directly await the MainActor:
await MainActor.run { settings.isFeatureEnabled = true }
This requires me to know that the settings
type is @MainActor
, even though the type is already decorated with it. It adds the complexity of additional scoping.
MainActor-isolated task:
Task { @MainActor in settings.isFeatureEnabled = true }
This has all the same problems as #2.
Why can't I just set the property?