Races, threads & the main actor

One phone, one thread for the UI

Every screen you've built since Module 5 has quietly relied on one rule: UIKit and SwiftUI only let you touch the screen from the main thread. That's why LiveTracker and every view model you've written is marked @MainActor β€” it pins the whole class to that one thread, so body never renders a half-updated phase while a background task is mid-write.

But apps do plenty of work that has nothing to do with drawing: hitting the API, parsing JSON, running the haversine sum over hundreds of GPS fixes. That work runs on background threads so the UI stays smooth β€” and the moment more than one thread can touch the same mutable value, you're one careless line away from a data race.