I wrote an app referred to as SwiftUI View Lifecycle. The app means that you can observe how totally different SwiftUI constructs and containers have an effect on a view’s lifecycle, together with the lifetime of its state and when onAppear
will get referred to as. The code for the app is on GitHub. It may be constructed for iOS and macOS.
After we write SwiftUI code, we assemble a view tree that consists of nested view values. Cases of the view tree are ephemeral: SwiftUI continually destroys and recreates (elements of) the view tree because it processes state modifications.
The view tree serves as a blueprint from which SwiftUI creates a second tree, which represents the precise view “objects” which can be “on display” at any given time (the “objects” might be precise UIView
or NSView
objects, but in addition different representations; the precise which means of “on display” can differ relying on context). Chris Eidhof likes to name this second tree the render tree (the hyperlink factors to a 3 minute video the place Chris demonstrates this duality, extremely beneficial).
The render tree persists throughout state modifications and is utilized by SwiftUI to ascertain view identification. When a state change causes a change in a view’s worth, SwiftUI will discover the corresponding view object within the render tree and replace it in place, somewhat than recreating a brand new view object from scratch. That is in fact key to creating SwiftUI environment friendly, however the render tree has one other essential perform: it controls the lifetimes of views and their state.
We are able to outline a view’s lifetime because the timespan it exists within the render tree. The lifetime begins with the insertion into the render tree and ends with the elimination. Importantly, the lifetime extends to view state outlined with @State
and @StateObject
: when a view will get faraway from the render tree, its state is misplaced; when the view will get inserted once more later, the state might be recreated with its preliminary worth.
The SwiftUI View Lifecycle app tracks three lifecycle occasions for a view and shows them as timestamps:
- @State = when the view’s state was created (equal to the beginning of the view’s lifetime)
- onAppear = when
onAppear
was final referred to as - onDisappear = when
onDisappear
was final referred to as
The app means that you can observe these occasions in numerous contexts. As you click on your means by means of the examples, you’ll discover that the timing of those occasions modifications relying on the context a view is embedded in. For instance:
- An
if
/else
assertion creates and destroys its youngster views each time the situation modifications; state is just not preserved. - A
ScrollView
eagerly inserts all of its youngsters into the render tree, no matter whether or not they’re contained in the viewport or not. All youngsters seem instantly and by no means disappear. - A
Listing
with dynamic content material (utilizingForEach
) lazily inserts solely the kid views which can be at present seen. However as soon as a toddler view’s lifetime has began, the listing will preserve its state alive even when it will get scrolled offscreen once more.onAppear
andonDisappear
get referred to as repeatedly as views are scrolled into and out of the viewport. - A
NavigationStack
callsonAppear
andonDisappear
as views are pushed and popped. State for mother or father ranges within the stack is preserved when a toddler view is pushed. - A
TabView
begins the lifetime of all youngster views instantly, even the non-visible tabs.onAppear
andonDisappear
get referred to as repeatedly because the person switches tabs, however the tab view retains the state alive for all tabs.
Listed here are just a few classes to remove from this:
- Totally different container views might have totally different efficiency and reminiscence utilization behaviors, relying on how lengthy they preserve youngster views alive.
onAppear
isn’t essentially referred to as when the state is created. It may occur later (however by no means earlier).onAppear
could be referred to as a number of occasions in some container views. In the event you want a aspect impact to occur precisely as soon as in a view’s lifetime, contemplate writing your self anonFirstAppear
helper, as proven by Ian Eager and Jordan Morgan in Operating Code Solely As soon as in SwiftUI (2022-11-01).
I’m positive you’ll discover extra attention-grabbing tidbits if you play with the app. Suggestions is welcome!