Sunday, September 4, 2022

The SwiftUI Render Loop

Rens Breur:

We will first look into a number of examples of such cases where it is useful to know how the SwiftUI render loop works. Then we will explore the render loop in more detail and ask questions such as: when exactly is the body of a SwiftUI view evaluated. Not “when” as in under what circumstances, but as in: at which point in time? Is a view always drawn on screen immediately after a body is evaluated? How related are body evaluation and screen rendering even? We sometimes use the word “render” for evaluating a body of a view, does that even make sense?


When it is not doing anything, a SwiftUI app will have an idle CFRunLoop. It will wait for events from an input source such as touches, network events, timers or a display refresh. In response to a touch, SwiftUI may call a Button's action handler. If we put a breakpoint inside that action handler, we will see __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ somewhere in the stack trace. This is because touch events are delivered from a type 0 input source.

In response to an action that we perform in response to an event from in input source, we might update some @State variable in a view or call a function on an @ObservedObject that in turns causes its objectWillChange publisher to fire. In this case, the SwiftUI view is invalidated. This means that its body needs to be re-evaluated, but it would be inefficient to do that immediately. Maybe the same function that changed a @State variable will change another @State variable. Therefore, the body evaluation is scheduled to be executed later.

Comments RSS · Twitter

Leave a Comment