I use Combine in viewModels to update the views. But if I store the AnyCancellable objects into a set of AnyCancellable, the deinit method is never called. I use the deinit to cancel all cancellables objects.
struct View1: View {
@ObservedObject var viewModel:ViewTextModel = ViewTextModel()
@Injected var appActions:AppActions
var body: some View {
VStack {
Text(self.viewModel.viewText)
Button(action: {
self.appActions.goToView2()
}) {
Text("Go to view \(self.viewModel.viewText)")
}
}
}
}
class ViewTextModel: ObservableObject {
@Published var viewText: String
private var cancellables = Set<AnyCancellable>()
init(state:AppState) {
// initial state
viewText = "view \(state.view)"
// updated state
state.$view.removeDuplicates().map{ "view \($0)"}.assign(to: \.viewText, on: self).store(in: &cancellables)
}
deinit {
cancellables.forEach { $0.cancel() }
}
}
Each time the view is rebuilt, a new viewmodel is instantiated but the old one is not destroyed. viewText
attribute is updated on each instance with state.$view.removeDuplicates().map{ "view \($0)"}.assign(to: \.viewText, on: self).store(in: &cancellables)
If I don't store the cancellable object in the set, deinit
is called but viewText
is not updated if the state's changed for the current view.
Do you have an idea of how to manage the update of the state without multiplying the instances of the viewmodel ?
Thanks