A SwiftUI View
that holds on to a model using @State
is having its model created and destroyed even when the View
is not changing.
This is under the new Observation
macro, running in Xcode 15.0, with a min deployment of iOS 17.
import SwiftUI
import Observation
struct ContentView: View {
@State var showView = false
var body: some View {
VStack {
PersonView()
Button("show view") {
showView.toggle()
}
if showView {
Text("new view")
}
}
}
}
@Observable
class Person {
var name: String
init(name: String) {
self.name = name
print("model create \(self.name)")
}
deinit {
print("model deinit \(self.name)")
}
}
struct PersonView: View {
@State private var model = Person(name: "swift")
var body: some View {
Text(model.name)
}
}
Expected: Tapping the button continuously I expected to see only this in the console.
model create swift
Actual: Tapping the button continuously produces this output in the console.
model create swift
model create swift
model create swift
model deinit swift
model create swift
model deinit swift
model create swift
model deinit swift
...
It's true, using @State with Observable causes a memory leak. It seems we'll have to wait until iOS 18 for another property wrapper that supports Observable since Apple were unable to address this in the beta cycle. In the meantime your object will need to be a singleton and just stick to structs for your model types. Eg make a PersonStore singleton observable object and have an array of Person structs.