Hello
I am trying to understand how to properly manage ObservableObject's (ObservedObject inside the SwiftUI View) lifecycle which was created in a view controller as a parent of a SwiftUI view. I have read many posts and rewatched these two videos and I am not still 100% sure https://developer.apple.com/wwdc20/10040 https://developer.apple.com/wwdc22/10072
So my dilemma boils down to whether it is needed to strongly retain the object by the parent view controller or not. In many sources including the videos it was mentioned that SwiftUI does NOT manage the lifecycle of the ObservedObject.
The SwiftUI view and the model (ObservableObject)
final class MyModel: ObservableObject {
// imagine this is somehow updated form somewhere
@Published var message = ""
}
struct MySwiftUIView: View {
@ObservedObject var myModel: MyModel
var body: some View {
Text("message is \(myModel.message)")
}
}
Option 1: View controller retaining the object
class MyViewController: UIViewController {
let myModel: MyModel // strong reference
let hostingController: UIHostingController<MySwiftUIView>
init() {
myModel = MyModel()
let mySwiftUIView = MySwiftUIView(myModel: myModel)
self.hostingController = UIHostingController(rootView: mySwiftUIView)
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Option 2: View controller NOT retaining the object
class MyViewController: UIViewController {
let hostingController: UIHostingController<MySwiftUIView>
init() {
let myModel = MyModel() // local retain for the `init` body
let mySwiftUIView = MySwiftUIView(myModel: myModel)
self.hostingController = UIHostingController(rootView: mySwiftUIView)
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Can i just use Option 2, and not retaining the observable object by the parent view controller or would that cause any issues?
Thank you in advance!
@filip-wsa both approaches are fine.
In the second example. the UIHostingController
retains MySwiftUIView, which would indirectly retaining myModel as well. I would suggest you look into the debug memory graph, you would observe that UIHostingController has a strong reference to the model object.