Понимание NSRunLoop


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

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

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

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

4 84

4 ответа:

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

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

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

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

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

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

EDIT

попытка обратиться к комментарию. Я разбил его на куски.

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

действительно. 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

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.

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

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

циклы запуска-это то, что отделяетinteractive приложения с инструменты.

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

С здесь

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

и с комментарий:

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

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

отсюда


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

отсюда