У тебя неправильное понимание.
По своей сути - поток выполняет свою задачу и умирает. Но это иногда плохо, ибо на создание тратятся ресурсы системы. Эту проблему можно решить несколькими способами... но один из них это
RunLoop.
RunLoop заставляет поток оставаться живым, даже если никакой задачи на нём не выполняется (Но это не основная его задача. Основная его задача "
слушать").
RunLoop стал настолько полезной штукой, что его принудительно привязали к каждому созданному потоку разработчики Apple. По-умолчанию,
RunLoop не активирован. То есть для обычных потоков вам даже и знать о нём не нужно. ДА вы даже не будете создавать потоки, ибо в 99% вы работаете с абстракциями
DispatchQueue/
OperationQueue.
Итак, когда
RunLoop активирован, то он заставляет поток жить всё время, пока активен он сам (Я напомню, что для
RunLoop это не основная цель).
RunLoop способен принимать какие-либо события, но это не тема этого разговора. Так вот... когда
RunLoop видит, что на "поле тишина", он переходит в спящий режим.
А спящий режим у
RunLoop это просто вечный цикл. Не верите?
Смотрите:
#define CFRUNLOOP_SLEEP() do { } while (0)
#define CFRUNLOOP_SLEEP_ENABLED() (0)