How does one publish a property from another ObservableObject
which is created during initialization?
I want to ensure a specific property is captured as a @Published
/@Binding
/@State
variable (so it's always kept updated in views), but I'm encountering an error when binding from an object that's also being created during the same init()
. For example:
The RandomOptionsManager
is an ObservableObject
which loads a list of options from a file:
class RandomOptionsManager: ObservableObject {
@Published var listCount: Int = 0
init() {
// Real code would load the list from a file
self.listCount = 150
}
}
The Randomizer
which uses it has a count property for how many options are available. I'm trying to get this as a @Binding
from the @Published
var in the options manager:
class Randomizer: ObservableObject {
@ObservedObject var optionsManager = RandomOptionsManager()
@Binding var listCount: Int
init() {
self._listCount = $optionsManager.listCount
}
}
However, this code results in an init error:
'self' used in property access '$optionsManager' before all stored properties are initialized
What's the correct configuration to avoid this issue?
As suggested in the question comments, this can be solved by avoiding @Binding
& @ObservedObject
(which are really for views, rather than other classes like this) and using assign(to:)
to republish the optionsManager's @Published var
as a new property.
This only requires code changes for the Randomizer
(the code for RandomOptionsManager
remains unchanged):
class Randomizer: ObservableObject {
@Published var listCount: Int = 0
private let optionsManager = RandomOptionsManager()
init() {
optionsManager.$listCount.assign(to: &self.$listCount)
}
}
Note that assign(to:)
automatically handles life-cycle management, so a separate explicit assignment to cancellable
is not required.