Понимание NSRunLoop

Может ли кто-нибудь объяснить, что такое NSRunLoop? так как я знаю, что NSRunLoop - это что-то связанное с NSThread правильно? Поэтому предположим, что я создаю Thread как

NSThread* th=[[NSThread alloc] initWithTarget:self selector:@selector(someMethod) object:nil];
[th start];

-(void) someMethod
{
    NSLog(@"operation");
}

Итак, после того, как эта нить заканчивает свое рабочее право? зачем использовать RunLoops или где использовать? из документов Apple я прочитал что-то, но это не понятно для меня, поэтому, пожалуйста, объясните как можно проще

Ответ 1

Запуск цикла - это абстракция, которая (среди прочего) обеспечивает механизм для обработки источников входных данных (сокетов, портов, файлов, клавиатуры, мыши, таймеров и т.д.).

Каждый NSThread имеет свой собственный цикл запуска, к которому можно получить доступ через метод currentRunLoop.

В общем, вам не нужно напрямую обращаться к циклу запуска, хотя есть некоторые (сетевые) компоненты, которые могут позволить вам указать, какой цикл цикла они будут использовать для обработки ввода-вывода.

Цикл запуска для данного потока будет ждать, пока один или несколько его источников входного сигнала будут иметь некоторые данные или событие, затем запустите соответствующий обработчик ввода для обработки каждого входного источника, который "готов".

После этого он вернется в свой цикл, обработает ввод из разных источников и "спящий", если нет работы.

Это довольно высокое описание уровня (попытка избежать слишком большого количества деталей).

ИЗМЕНИТЬ

Попытка ответить на комментарий. Я разбил его на части.

  • это означает, что я могу только получить доступ/запустить, чтобы запустить цикл внутри потока не так ли?

Действительно. NSRunLoop не является потокобезопасным и должен быть доступен только из контекста потока, который запускает цикл.

  • Есть ли какой-нибудь простой пример того, как добавить событие в цикл цикла?

Если вы хотите контролировать порт, вы просто добавите этот порт в цикл выполнения, а затем цикл выполнения будет наблюдать за этим портом для активности.

- (void)addPort:(NSPort *)aPort forMode:(NSString *)mode

Вы также можете добавить таймер с помощью

- (void)addTimer:(NSTimer *)aTimer forMode:(NSString *)mode
  • что означает, что он вернется в цикл?

Запуск цикла будет обрабатывать все готовые события на каждой итерации (в соответствии с его режимом). Вам нужно будет посмотреть документацию, чтобы узнать о режимах запуска, поскольку это немного выходит за рамки общего ответа.

  • запускает цикл неактивным при запуске потока?

В большинстве приложений основной цикл запуска запускается автоматически. Однако вы несете ответственность за запуск цикла выполнения и реагирование на входящие события для потоков, которые вы вращаете.

  • Можно ли добавить некоторые события в цикл цикла Thread за пределами потока?

Я не уверен, что вы имеете в виду здесь. Вы не добавляете события в цикл выполнения. Вы добавляете источники входного сигнала и источники таймера (из потока, которому принадлежит цикл запуска). Затем цикл цикла отслеживает их активность. Конечно, вы можете предоставить ввод данных из других потоков и процессов, но ввод будет обрабатываться циклом запуска, который контролирует эти источники в потоке, который запускает цикл выполнения.

  • означает ли это, что иногда я могу использовать run loop для блокировки потока на время

Действительно. Фактически, цикл цикла будет "оставаться" в обработчике событий, пока этот обработчик события не вернется. Вы можете видеть это в любом приложении достаточно просто. Установите обработчик для любого действия ввода-вывода (например, нажатия кнопки), которое будет спать. Вы заблокируете цикл основного запуска (и весь пользовательский интерфейс) до тех пор, пока этот метод не завершится.

То же самое относится к любому циклу запуска.

Я предлагаю вам прочитать следующую документацию по циклам запуска:

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

Ответ 2

RunLoops - это что-то вроде коробки, где вещи просто случаются.

Обычно в RunLoop вы обрабатываете некоторые события и затем возвращаетесь. Или вернитесь, если он не обрабатывает события до истечения времени ожидания. Вы можете сказать, что это похоже на асинхронную NSURLConnections, обработку данных в фоновом режиме, не влияя на ваш текущий цикл, и в то же время, вам требуются данные синхронно. Что можно сделать с помощью RunLoop, который выполняет асинхронное соединение NSURLConnection и предоставляет данные во время вызова. Вы можете использовать RunLoop следующим образом:

NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1];

while (YourBoolFlag && [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:loopUntil]) {
    loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1];
}

В этом RunLoop он будет работать до тех пор, пока вы не завершите какую-либо другую работу и не установите YourBoolFlag в false.

Точно так же вы можете использовать их в потоках.

Надеюсь, это поможет вам.

Ответ 3

Циклы выполнения - это то, что отделяет интерактивные приложения от инструментов командной строки.

  • Инструменты командной строки запускаются с параметрами, выполняют их команду, а затем завершаются.
  • Интерактивные приложения ждут ввода пользователя, реагируют, затем возобновляют ожидание.

Отсюда

Они позволяют вам ждать, пока пользователь нажмет и ответит соответственно, подождать, пока вы не получите завершение, и применить его результаты, дождаться, пока вы получите таймер и выполнить функцию. Если у вас нет runloop, то вы не можете прослушивать/ждать пользовательских нажатий, вы не можете ждать, пока не произойдет сетевой вызов, вы не сможете проснуться через x минут.

Также из этого комментария:

Фоновые потоки не имеют своих собственных циклов выполнения, но вы можете просто добавить их. Например, AFNetworking 2.x сделал это. Это была опробованная и истинная методика для NSURLConnection или NSTimer в фоновых потоках, но мы сами больше этого не делаем, поскольку новые API избавляют от необходимости делать это. Но похоже, что URLSession выполняет, например, простой запрос, выполняя [см. Левую панель изображения] обработчики завершения в главной очереди, и вы можете видеть, что он имеет цикл выполнения в фоновом потоке

Ответ 4

Циклы выполнения являются частью фундаментальной инфраструктуры, связанной с потоками. Цикл выполнения - это цикл обработки событий, который вы используете для планирования работы и координации приема входящих событий. Цель цикла выполнения состоит в том, чтобы сохранить ваш поток занятым, когда есть работа, и перевести ваш поток в спящий режим, когда его нет.

Отсюда


Наиболее важной особенностью CFRunLoop является CFRunLoopModes. CFRunLoop работает с системой "Run Loop Sources". Источники регистрируются в цикле выполнения для одного или нескольких режимов, и сам цикл выполнения выполняется для выполнения в данном режиме. Когда событие поступает в источник, оно обрабатывается циклом выполнения, только если режим источника соответствует текущему режиму цикла выполнения.

Отсюда