Цикл выполнения - это абстракция, которая (среди прочего) предоставляет механизм для обработки системных источников ввода (сокеты, порты, файлы, клавиатура, мышь, таймеры и т. Д.).
Каждый NSThread имеет свой собственный цикл выполнения, доступ к которому можно получить с помощью метода currentRunLoop.
В общем, вам не нужно напрямую обращаться к циклу выполнения, хотя есть некоторые (сетевые) компоненты, которые могут позволить вам указать, какой цикл выполнения они будут использовать для обработки ввода-вывода.
Цикл выполнения для данного потока будет ждать, пока один или несколько его источников ввода не получат какие-либо данные или событие, а затем запустят соответствующий обработчик (ы) ввода для обработки каждого источника ввода, который «готов».
После этого он вернется в свой цикл, обрабатывая входные данные из различных источников и «спит», если нет работы.
Это довольно подробное описание (попытка избежать слишком большого количества деталей).
РЕДАКТИРОВАТЬ
Попытка ответить на комментарий. Я разбил его на части.
- это означает, что я могу получить доступ / запустить цикл только внутри потока, верно?
На самом деле. NSRunLoop не является потокобезопасным, и к нему следует обращаться только из контекста потока, в котором выполняется цикл.
- есть ли простой пример, как добавить событие в цикл выполнения?
Если вы хотите отслеживать порт, вы просто добавляете этот порт в цикл выполнения, а затем цикл выполнения будет отслеживать активность этого порта.
- (void)addPort:(NSPort *)aPort forMode:(NSString *)mode
Вы также можете явно добавить таймер с помощью
- (void)addTimer:(NSTimer *)aTimer forMode:(NSString *)mode
- что означает, что он вернется в свой цикл?
Цикл выполнения будет обрабатывать все события готовности на каждой итерации (в соответствии со своим режимом). Вам нужно будет просмотреть документацию, чтобы узнать о режимах запуска, поскольку это немного выходит за рамки общего ответа.
- цикл выполнения неактивен, когда я запускаю поток?
В большинстве приложений основной цикл выполнения запускается автоматически. Однако вы несете ответственность за запуск цикла выполнения и реагирование на входящие события для потоков, которые вы запускаете.
- можно ли добавить некоторые события в цикл выполнения потока вне потока?
Я не понимаю, что вы здесь имеете в виду. Вы не добавляете события в цикл выполнения. Вы добавляете источники ввода и источники таймера (из потока, которому принадлежит цикл выполнения). Затем цикл выполнения отслеживает их активность. Вы, конечно, можете обеспечить ввод данных из других потоков и процессов, но ввод будет обрабатываться циклом выполнения, который отслеживает эти источники в потоке, в котором выполняется цикл.
- означает ли это, что иногда я могу использовать цикл выполнения для блокировки потока на время
На самом деле. Фактически, цикл выполнения будет «оставаться» в обработчике событий до тех пор, пока этот обработчик событий не вернется. Вы можете достаточно просто увидеть это в любом приложении. Установите обработчик для любого действия ввода-вывода (например, нажатия кнопки), которое засыпает. Вы заблокируете основной цикл выполнения (и весь пользовательский интерфейс), пока этот метод не завершится.
То же самое относится к любому циклу выполнения.
Я предлагаю вам прочитать следующую документацию по циклам выполнения:
https://developer.apple.com/documentation/foundation/nsrunloop
и как они используются в потоках:
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW1