At a high level, there are real time threads (which run until they block) and time share threads, which have a base priority. The time share thread with the highest priority runs on the CPU but, as it runs, its priority decays. Eventually that priority drops below that of some other time share thread, and the CPU switches threads.
The mechanics of this are very complex. If you want to get deeper into it, you can take a look at Mac OS X Internals, by Singh. It’s way out of date, but it’s still a great read.
If you want to get really deep into it, iOS uses (more or less) the same Darwin kernel as macOS, and you can its source code from the Darwin site (look for the xnu project).
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"