runloop swift что это такое
IOS Run Loop: Что? Когда? Зачем?
Run Loop (цикл исполнения) является механизмом, который позволяет потокам обрабатывать события (events) бесконечно в любое время.
Run Loop представляет из себя объект, который управляет событиями и сообщениями, обрабатывает их, и предоставляет функцию точки входа для выполнения логики события.
В OSX/iOS у нас уже есть реализация этого механизма в виде NSRunLoop и CFRunLoopRef. CFRunLoopRef является частью фреймворка CoreFoundation. Он предоставляет API для функций на чистом C, которое является потокобезопасным.
NSRunLoop — это обертка, берущая за основу CFRunLoopRef, которая предоставляет объектно-ориентированное API, но это API не является потокобезопасным.
В системе по умолчанию предусмотрено пять режимов:
kCFRunLoopDefaultMode: дефолтный для вашего приложения режим, обычно в этом режиме выполняется основной (main) поток.
UITrackingRunLoopMode: режим отслеживания интерфейса, используемый ScrollView для отслеживания касаний и слайдов, чтобы гарантировать, что интерфейс не зависит от других режимов при слайдинге.
UIInitializationRunLoopMode: первый режим, в который приложение входит при запуске, он не будет больше использоваться после завершения запуска.
GSEventReceiveRunLoopMode: внутренний режим для приема системных событий, обычно не используется.
kCFRunLoopCommonModes: это режим-заполнитель, не имеющий практического значения.
Четыре функции цикла исполнения:
Принимать вводимые пользователем данные, не прерывая выполнения программы.
Решать, когда события должны обрабатываться программой.
Экономить время процессора
Цикл исполнения основного потока запускается по умолчанию. В iOS-приложении после запуска функция main() будет следующей:
Ключевым моментом является функция UIApplicationMain(). Этот метод устанавливает объект NSRunLoop для основного потока (main thread).
Это объясняет, почему наше приложение может находиться в состоянии сна, когда мы с ним не взаимодействуем (никакие действия не выполняются) и в то же время немедленно реагировать, когда какое-либо действие наконец совершается.
Для других потоков цикл исполнения по умолчанию не запускается. Если вам нужно больше интерактивности с потоками, вы можете вручную настроить и запустить его. Если поток выполняет только долгосрочную заранее заданную задачу, то в этом нет необходимости. В любом потоке Cocoa-программы вы можете сделать следующее, чтобы запустить цикл исполнения в текущем потоке.
Цикл исполнения (run loop) — это цикл обработки событий, который используется для непрерывного мониторинга и обработки входящих событий и назначения их соответствующим таргетам для дальнейшей обработки.
NSRunLoop — более умная модель обработки сообщений. Он умело абстрагировал и инкапсулировал процесс обработки сообщений, чтобы вам не приходилось иметь дело с очень тривиальной и низкоуровневой конкретикой обработки сообщений. Каждое сообщение упаковано в источник ввода (input source) или источник таймера (timer source). Использование цикла исполнения позволяет вашему потоку работать, когда есть работа, и переходить в спящий режим, когда работы нет, что может значительно сэкономить системные ресурсы.
Изображение взято со stackoverflow. Ссылка ниже.
Когда следует использовать цикл исполнения?
Cocoa предоставляет код для запуска основного цикла (main loop) программы и автоматического запуска цикла исполнения. Метод запуска UIApplication в программе IOS (или NSApplication в Mac OS X) используется как часть этапа запуска программы. Он запустит основной цикл программы, когда будет завершен ее запуск.
Для вспомогательных же потоков вам самим необходимо определить, нужны ли им циклы исполнения. Если нужны, то вам придется настроить и запустить их самостоятельно. По умолчанию вам не рекомендуется запускать цикл исполнения для потока ни при каких обстоятельствах. Например, когда вы используете потоки для обработки заранее определенной длительной задачи, вам следует избегать запуска цикла исполнения. Запуск цикла исполнения оправдан только если вы хотите активно взаимодействовать с потокам, например:
использовать кастомные порты или источники ввода для коммуникации с другими потоками
использовать потоковые таймеры (threaded timers)
использовать метод Cocoa с любым performSelector’ом
перевести поток в режим периодической работы
NSRunLoop класс в Cocoa не потокобезопасен
Мы не можем управлять объектом цикла исполнения одного потока в другом потоке — это может привести к неожиданным результатам. К счастью, opaque класс CFRunLoopRef в CoreFundation является потокобезопасным, что позволяет миксовать между собой типы циклов исполнения. Класс NSRunLoop в Cocoa может быть реализован с помощью методов инстанса:
Остается только выберать соответствующий класс CFRunLoopRef для обеспечения потокобезопасности.
Управление циклом исполнения не является полностью автоматическим
Нам все еще нужно писать в потоке код, запускающий цикл исполнения в подходящее время, и должным образом реагировать на события, конечно, если цикл исполнения необходим в этом потоке. Более того, нам также нужно использовать операторы while/for, чтобы сделать цикл исполнения бесконечным. Следующий код успешно запускает цикл исполнения:
Цикл исполнения также отвечает за создание и выпуск autorelease пула.
Материал подготовлен в рамках курса «iOS Developer. Professional». Если вам интересно узнать подробнее о формате обучения и программе, познакомиться с преподавателем курса — приглашаем на день открытых дверей онлайн. Регистрация здесь.
Русские Блоги
Подробное объяснение и практика iOS RunLoop
оглавление
-Концепция RunLoop
-RunLoop логика и реализация
-RunLoop используется в iOS
-RunLoop практика
-Концепция RunLoop
В документации Apple RunLoop определяется следующим образом:
Run loops are part of the fundamental infrastructure associated with threads.
A run loop is an event processing loop that you use to schedule work and coordinate the receipt of incoming events. The purpose of a run loop is to keep your thread busy when there is work to do and put your thread to sleep when there is none.
RunLoop Основная функция, связанная с потоками, RunLoop Он используется для планирования работы и координации цикла обработки событий, который принимает входящие события. RunLoop Цель состоит в том, чтобы позволить потоку работать, когда есть задача, и спать, когда нет задачи для обработки.
Работающий цикл получает события из двух разных типов источников. Источник ввода доставляет асинхронные события, обычно сообщения из другого потока или из другого приложения. Событие синхронизации, предоставляемое источником синхронизации, которое происходит в заранее определенное время или интервал повторения. Оба типа источников используют процедуры обработки, зависящие от приложения, когда они прибывают для обработки события.
-RunLoop логика и реализация
CFRunLoopTimerRef Это триггер на основе времени, который можно смешивать с NSTimer, включая длину времени и обратный вызов, добавить
Когда RunLoop, RunLoop зарегистрирует соответствующую точку времени, когда точка времени, RunLoop будет активирован для выполнения этого обратного вызова
CFRunLoopObserverRef Наблюдатель, каждый Observer Оба включают обратный вызов (указатель на функцию). Когда состояние RunLoop изменяется, наблюдатель может получить это изменение через обратный вызов. Моменты времени, которые можно наблюдать, следующие:
-RunLoop используется в iOS
Роль Run Loop
1. Продолжайте работу программы и примите ввод пользователя.
2. Решите, когда программа должна обрабатывать эти события.
3. Разделение вызовов (очередь сообщений)
4. Экономьте процессорное время.
Когда звонить
1. Использовать порт port Или настраиваемый источник ввода input sources Общайтесь с другими темами
2. Используйте таймер потока timer
3. Используйте любой метод performSelector в Какао.
4. Поток выполняет периодические задачи.
Сценарии приложения RunLoop
AutoreleasePool
Вызов стека среды выполнения приложения основного потока
При запуске программы Apple находится в основном потоке RunLoop Добавлены два Observer Для мониторинга RunLoop из kCFRunLoopEntry (Вызвать) и BeforeWating (Готов спать)
GCD
GCD и RunLoop Часть реализации использует друг друга, RunLoop из timer Используется dispatch_source_t Достигнуто, а GCD dispatch_async() Также используется RunLoop
При звонке dispatch_async(dispatch_get_main_queue(), block) Время, dispatch Основной поток RunLoop Послать сообщение, RunLoop Буду разбужен и получу от сообщения block Отправить обратный звонок
Сетевой запрос
основан на CFNetwork из NSURLConnection Инициирован NSURLConnectionLoader В потоке цикл выполнения основан на mach port из Source0 Получите из нижнего слоя CFSocket Обратите внимание, просыпайтесь одновременно delegate с участием RunLoop Для обработки этих уведомлений.
Используется ответ на событие __IOHIDEventSystemClientQueueCallback()
Используется распознавание жестов _UIGestureRecognizerUpdateObserver()
Используется обновление интерфейса _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv()
и т. д.
Практика RunLoop
// RunLoop-Поддержание жизненного цикла потока, чтобы поток не выходил автоматически, завершаемся, когда isFinished имеет значение Yes. Перед запуском RunLoop необходимо добавить отслеживаемый порт или источники событий источника ввода или таймер событий источника синхронизации, в противном случае вызов [runloop run] вернется напрямую, не входя в цикл, чтобы позволить потоку остаться. Если событие источника ввода или событие таймера не добавлено, поток всегда будет бездействовать в бесконечном цикле, всегда будет занимать срез времени ЦП, и разумное распределение ресурсов не будет реализовано. Если цикла while нет и к потоку не добавлен источник ввода или таймер, поток завершится напрямую и будет повторно использован системой.
// Новая идея tableView задержки загрузки изображений
// RunLoop-NSTimer работает в разных режимах
// RunLoop-NSTimer создает таймер в потоке
// RunLoop-RunLoop используется в RCTWebSocket в среде ReactNative
// AFURLRequestSerilization RunLoop AFNetWorking
// AFURLConnectionOperationRunLoop использовал резидентные потоки в предыдущих версиях AFNetworking
Релевантная информация:
Официальные документы Справочник по классам NSRunLoop, Справочник по CFRunLoop.
Код CFRunLoopRef:Открытый источникДа вы можете здесьhttp://opensource.apple.com/tarballs/CF/ Загрузите исходный код всего CoreFoundation для просмотра.
Быстрая версия кроссплатформенного CoreFoundation:https://github.com/apple/swift-corelibs-foundation/, Исходный код этой версии может немного отличаться от реализации в существующей системе iOS, но ее легче компилировать, и она адаптирована для Linux / Windows.
Интеллектуальная рекомендация
Совместное использование сухих товаров GitHub (высокая степень интеграции страницы руководства APP-DHGuidePageHUD)
Каждое приложение будет использовать страницу руководства APP, которая не важна, но обязательна. Будь то первая установка приложения или обновление версии, это единственное, что будет показано пользов.
Организуйте некоторые элементы управления диаграммами, которые можно использовать в веб-разработке, в основном для клиентских реализаций, таких как Flash, JavaScript, Silverlight; если для создания ст.