I am trying to learn how SwiftUI works internally in terms of memory management. I have little doubt about it.
When I add a NavigationLink to the 2nd View which has some Search Functionality and also loading some data from the cloud.
Now when I came back to the root view, my observableObject class is still in memory.
Does anyone have any idea how SwiftUI manages the memory and release objects?
Here is a sample code of my experiment.
struct ContentView: View {
var body: some View {
NavigationView {
DemoView(screenName: "Home")
.navigationBarHidden(true)
}
}
}
struct DemoView:View {
var screenName:String
var body: some View {
VStack{
NavigationLink(destination: SecondView(viewModel:SecondViewModel())) {
Text("Take Me To Second View")
}
Text(self.screenName)
}
}
}
// Second View
class SecondViewModel:ObservableObject {
@Published var search:String = ""
@Published var user:[String] = []
func fetchRecords() -> Void {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) { [weak self] in
self?.user = ["Hello", "There"]
}
}
}
struct SecondView:View {
@ObservedObject var viewModel:SecondViewModel
var body: some View {
VStack {
TextField("Search Here", text: $viewModel.search)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
List(self.viewModel.user, id:\.self) { user in
Text("User \(user)")
}
}.onAppear{
self.viewModel.fetchRecords()
}
}
}
And this is what I received in-memory graph.
The object lifecycle in SwiftUI is as usual. An object is deallocated by ARC when there are no more references to it. You can add
deinit { print("deinit")}
to yourSecondViewModel
and see when the object is deallocated. And yes, in your case a newSecondViewModel
object will be created each time theDemoView
body is evaluated, which is probably not what you want. I guggest you initialize and store theSecondViewModel
object outside of the view hierarchy, and pass a reference to this global object inDemoView.body
.