6.3 · The run loop, its modes, and the main-thread contract
Everything on screen happens because a loop on the main thread woke up, handled something, and went back to sleep. Knowing how that loop works explains frozen timers, stuck UI and odd ordering.
Mental model. A run loop is “sleep until something happens, handle it, repeat”. Timers, touches, display updates and the main queue are all things it wakes up for.
How the loop runs
Sources, timers, observers, and one trip around the loop.
- What is a run loop, and what happens in one iteration?
A run loop is an event loop attached to a thread. Its job: block cheaply until there is work, process it, block again. Inside it, work comes from sources… - What are run loop modes, and why does a Timer stop firing while the user scrolls?
A run loop runs in one mode at a time, and each mode has its own set of sources, timers and observers; only the ones registered for the current mode fire. The…
The main thread
What it must do, and what must stay off it.
- What is the main-thread contract, and why does DispatchQueue.main.sync from the main thread crash?
UIKit and most of SwiftUI’s view layer are main-thread only: you create and update views, touch layout and read many properties on the main thread. This is…
More in iOS platform internals
- 6.1 · The process, the sandbox, entitlements and privacy prompts
- 6.2 · App and scene lifecycle in UIKit and SwiftUI
- 6.4 · The launch path: dyld, initialisers and the first frame
- 6.5 · Background modes, BGTaskScheduler and background transfers
- 6.6 · Memory warnings, jetsam and the watchdog
- 6.7 · Info.plist, URL schemes, universal links and associated domains
- 6.8 · App groups, keychain groups and extensions as separate processes
- 6.9 · How a process dies, what it costs, what confines it and what seals it
- 6.10 · Threads and run loops, observers, and what actually runs in a custom mode
- 6.11 · Launch arguments, the scene callbacks, and reading a binary and its plists