8.10 · State, bindings, Observation and environment, checked by running them
Most SwiftUI state bugs come from not knowing when an initialiser runs, what a tracking scope really saw, or what a binding is. Each of these was run: in an iOS Simulator through UIHostingController, or as a plain program where no rendering is needed.
Mental model. A view struct is a throw-away description; its state lives in the graph. Ask three things of any value: who owns it, who read it during body, and what notifies when it changes.
Where state lives
When initialisers run, and how a binding is just a getter and a setter.
- A view’s init runs on every parent update. When does the initial value of @State or @StateObject actually get created?
The view struct is rebuilt every time a parent’s body runs, so its init runs again and again. The check counts it: after the first render and three parent… - What is a Binding really, and how do derived, constant and transforming bindings behave?
A Binding stores no value: it is a getter and a setter (plus a transaction). $state hands you one that reads and writes the state’s storage; Binding(get:set:)…
What gets tracked
Observation granularity, the older ObservableObject, environment and stored preferences.
- What exactly does Observation track: computed properties, ignored properties, collections, nested objects and equal writes?
withObservationTracking (what SwiftUI wraps around body) records every property read during the tracking closure and fires once when any of them changes. The… - When exactly does ObservableObject publish, and why do nested objects and equal assignments surprise people?
@Published sends objectWillChange before the new value is stored. In the check the sink runs while title is still t, and the $title publisher likewise delivers… - If a parent changes one environment value, which child views re-run their body?
The environment is tracked per key. In the check the parent sets a custom level value (declared with the @Entry macro) around three children. When level… - How does @AppStorage behave: where is the value, what happens when it is removed or changed elsewhere, and what can you store?
@AppStorage("key") var n = 3 reads and writes UserDefaults (the standard suite unless you pass store:). The declared value is only a default: it is not written…
More in SwiftUI
- 8.1 · What a View is, and how SwiftUI knows which view is which
- 8.2 · The update loop, dependency tracking and the cost of body
- 8.3 · State, Binding, Environment and Observation
- 8.4 · onAppear, task, onChange and scenes
- 8.5 · The layout negotiation, stacks, GeometryReader, safe area and custom Layout
- 8.6 · Lists, ForEach and NavigationStack
- 8.7 · Animations, PhaseAnimator, Canvas and TimelineView
- 8.8 · Preference keys and coordinate spaces
- 8.9 · Previews and the macros behind SwiftUI
- 8.11 · The order of events in a render, and what Swift 6 isolation means for views
- 8.12 · Sharing space, alignment guides, adaptive containers and grids, measured
- 8.13 · What a ViewBuilder produces, and saving and restoring a navigation path