What is the difference between ObservedObject and StateObject in SwiftUI
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
@ObservedObject and @StateObject both connect a SwiftUI view to an ObservableObject, but they differ in ownership and lifetime. That is the core distinction. If the view owns and creates the object, use @StateObject. If the object is created elsewhere and merely passed in, use @ObservedObject.
Use @StateObject When the View Owns the Object
A @StateObject is initialized once for the lifetime of that view identity and kept alive by SwiftUI.
This is the right choice because CounterScreen creates the model and expects it to survive normal view redraws.
If you used @ObservedObject here instead, SwiftUI could recreate the object more often than you intended, leading to lost state.
Use @ObservedObject When Ownership Is External
An @ObservedObject is for a view that observes an object created elsewhere.
Here the child view does not own the object. It just watches it. That is exactly what @ObservedObject is for.
The parent owns the lifetime. The child observes the updates.
The Wrong Wrapper Usually Shows Up as Reset State
A common bug is creating an observable object inside a view with @ObservedObject.
This compiles, but it creates the wrong ownership model. If SwiftUI recreates the view, the object can be recreated too, which leads to state resets or surprising lifecycle behavior.
That is the bug @StateObject was introduced to solve.
Think About Lifetime, Not Just Redraws
SwiftUI views are value types and are recreated frequently. Your object model often should not be. The property wrapper decides whether SwiftUI should preserve the observable object across view updates or simply subscribe to one supplied from somewhere else.
That is why the right mental model is not "which one updates the view." Both do that. The right mental model is "who owns this object and who is responsible for keeping it alive."
Parent-Child Structure Usually Makes the Choice Obvious
A good rule of thumb is:
- root or owning view:
@StateObject - dependent child view:
@ObservedObject
That rule is not about hierarchy for its own sake. It is about having one clear owner.
If several views all think they own the same model, lifecycle bugs follow quickly.
@EnvironmentObject Is Yet Another Ownership Pattern
It helps to place these wrappers in context:
- '
@StateObject: this view owns the object' - '
@ObservedObject: this view observes an externally owned object' - '
@EnvironmentObject: the object is injected from the environment'
That comparison prevents a common confusion where developers treat @ObservedObject and @StateObject as if they were interchangeable update mechanisms.
Common Pitfalls
- Creating an object inside a view with
@ObservedObjectinstead of@StateObject. - Using
@StateObjectin a child view that does not actually own the model. - Thinking the wrappers differ in whether updates happen instead of in who owns the object.
- Debugging random state resets without checking whether the object wrapper matches the intended lifetime.
- Treating
@ObservedObject,@StateObject, and@EnvironmentObjectas synonyms.
Summary
- Both wrappers observe
ObservableObjectchanges, but they solve different ownership problems. - Use
@StateObjectwhen the view creates and owns the object. - Use
@ObservedObjectwhen the object comes from elsewhere. - The main symptom of using the wrong wrapper is unexpected object recreation and lost state.
- In most parent-child designs, the parent owns with
@StateObjectand the child observes with@ObservedObject.

