@Observable replaces ObservableObject: what actually changes

SwiftUIiOSSwift

ObservableObject aged well for its era, but it has a structural flaw: a view observing an object redraws as soon as any of its @Published properties changes - including the ones it never displays.

@Observable fixes that at the compiler level. Here is what changes in practice.

The global re-render problem

With ObservableObject, the subscription happens at the object level, not the property level. A screen that only displays user.name redraws when user.lastSyncDate changes in the background.

On a list of 200 cells sharing the same store, you can see it.

What @Observable does

The macro instruments every property. SwiftUI then records exactly which properties were read during body, and invalidates the view only when one of those changes.

@Observable
@MainActor
final class LibraryStore {
    var books: [Book] = []
    var lastSyncDate: Date?
}

No @Published, no objectWillChange. Tracking is automatic.

How to migrate a screen

  1. Replace ObservableObject with @Observable, delete every @Published.
  2. @StateObject becomes @State, @ObservedObject goes away (a plain property is enough), @EnvironmentObject becomes @Environment.
  3. For a binding to the object, use @Bindable.
struct LibraryView: View {
    @State private var store = LibraryStore()

    var body: some View {
        List(store.books) { book in
            Text(book.title)
        }
    }
}

The traps

  • Properties read outside body are not tracked. If the value is read in a closure that runs later, observation never fires.
  • @Observable is not thread-safe. Mark the class @MainActor unless the project already enables global main-actor isolation.
  • No retroactive conformance. A type cannot be both @Observable and ObservableObject, so migration happens one full screen at a time.

Verdict

On a simple screen the gain is invisible. On a list fed by a shared store the difference in smoothness is immediate - and the code sheds a third of its annotations along the way.

← All articles