Explains the difference between SwiftUI's @StateObject and @ObservedObject property wrappers: use @StateObject when a view creates and owns an ObservableObject, and @ObservedObject when the view receives one from a parent. Covers common pitfalls like creating an object inline with @ObservedObject, which causes it to reset when SwiftUI recreates the view. Also touches on the newer Observation framework (@Observable and @State) as the recommended approach for iOS 17+ projects, while noting @StateObject/@ObservedObject remain relevant for older OS support or existing ObservableObject models.
Table of contents
@StateObject vs. @ObservedObjectWhat is an @ObservedObject ?What is a @StateObject?StateObject vs. ObservableObjectWhat about @Observable ?When should you use each property wrapper?Questions this post answers
When should I use @StateObject versus @ObservedObject in SwiftUI?
Use @StateObject when the view creates and owns the ObservableObject, and @ObservedObject when the view receives the object from a parent. Only @StateObject preserves the object's lifetime across view updates; creating an object inline with @ObservedObject causes SwiftUI to recreate it whenever the parent view rebuilds, resetting its state. daily.dev surfaces SwiftUI patterns like this for developers debugging state resets in their views.
Why does my SwiftUI view model reset its state every time the parent view updates?
This happens when an ObservableObject is created inline using @ObservedObject instead of @StateObject. Since @ObservedObject provides no persistent storage, SwiftUI can recreate the object each time it rebuilds the view's value, wiping out any accumulated state such as a counter. Switching the property wrapper to @StateObject fixes it by preserving the object across view identity. Developers chasing SwiftUI state bugs like this can find related fixes on daily.dev.
Should I replace ObservableObject and @StateObject with @Observable in new SwiftUI code?
Yes, for code targeting iOS 17 and later, the Observation framework's @Observable macro combined with @State is recommended instead of ObservableObject, @Published, and @StateObject. An injected @Observable model typically needs no property wrapper, and @Bindable is only required when a child view needs bindings to the model's properties. daily.dev helps iOS developers weighing @Observable against ObservableObject stay on top of SwiftUI migration guidance.