What are they?

@StateObject and @ObservedObject are property wrappers in SwiftUI used to manage state in your app. They both work with objects that conform to the ObservableObject protocol.

Understand With Video

@StateObject
  • Creates and owns the object
  • Keeps the object alive for the lifetime of the view
  • Used for data that the current view is responsible for creating
@ObservedObject
  • Doesn't create the object, just observes it
  • Doesn't keep the object alive
  • Used for data passed into the view from somewhere else
When to use @StateObject
  1. When the view is creating its own model object
  2. For long-lived objects that should persist even if the view refreshes
  3. Typically used in the root view or a view that owns the data

Example:

class UserSettings: ObservableObject {
    @Published var username = "Guest"
}

struct ContentView: View {
    @StateObject private var settings = UserSettings()
    
    var body: some View {
        Text("Hello, \(settings.username)!")
    }
}
When to use @ObservedObject
  1. When the object is created and owned by a parent view
  2. For objects passed as parameters to the view
  3. When you want to observe changes but don't need to control the object's lifecycle

Example:

struct DetailView: View {
    @ObservedObject var settings: UserSettings
    
    var body: some View {
        Text("Hello, \(settings.username)!")
    }
}

struct ContentView: View {
    @StateObject private var settings = UserSettings()
    
    var body: some View {
        DetailView(settings: settings)
    }
}
Best Practices
  1. Use @StateObject for objects created by the current view
  2. Use @ObservedObject for objects passed into the view
  3. Create objects at the highest necessary level in your view hierarchy
  4. Avoid creating multiple instances of the same object
Summary

Think of @StateObject as the "owner" and @ObservedObject as the "borrower". If your view is responsible for creating and managing the object, use @StateObject. If your view is just using an object created elsewhere, use @ObservedObject.