Понимание 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 ответов
цикл выполнения-это абстракция, которая (среди прочего) предоставляет механизм для обработки системных источников ввода (сокетов, портов, файлов, клавиатуры, мыши, таймеров и т. д.).
каждый NSThread имеет свой собственный цикл выполнения, к которому можно получить доступ с помощью метода currentRunLoop.
В общем случае вам не нужно напрямую обращаться к циклу выполнения, хотя есть некоторые (сетевые) компоненты, которые могут позволить вам указать, какой цикл выполнения они будут использовать для ввода-вывода обработка.
цикл выполнения для данного потока будет ждать, пока один или несколько его источников ввода не будут иметь некоторые данные или событие, а затем запустите соответствующий обработчик(ы) ввода для обработки каждого источника ввода, который "готов.".
после этого он вернется к своему циклу, обрабатывая входные данные из разных источников и "спящий", если нет работы.
это довольно высокое описание уровня (пытаясь избежать слишком многих подробная информация.)
редактировать
попытка обратиться к комментарию. Я разбил его на куски.
- это означает, что я могу только открыть/запустить, чтобы запустить цикл внутри потока правильно?
действительно. NSRunLoop не является потокобезопасным и должен быть доступен только из контекста потока, в котором выполняется цикл.
- есть ли простой пример как добавить событие на запуск петля?
Если вы хотите контролировать порт, вы просто добавите этот порт в цикл выполнения, а затем цикл выполнения будет следить за этим портом для активности.
- (void)addPort:(NSPort *)aPort forMode:(NSString *)mode
вы также можете добавить таймер явно с
- (void)addTimer:(NSTimer *)aTimer forMode:(NSString *)mode
- что означает, что он вернется к своему циклу?
цикл выполнения будет обрабатывать все готовые события на каждой итерации (в соответствии с ее режимом). Вы должны смотреть на документация, чтобы узнать о режимах запуска, так как это немного выходит за рамки общего ответа.
- цикл запуска неактивен при запуске потока?
в большинстве приложений основной цикл выполнения будет выполняться автоматически. Однако вы несете ответственность за запуск цикла выполнения и ответ на входящие события для потоков, которые вы вращаете.
- можно ли добавить некоторые события в цикл выполнения потока вне нити?
Я не уверен, что вы подразумеваете здесь. События не добавляются в цикл выполнения. Вы добавляете источники ввода и источники таймера (из потока, которому принадлежит цикл выполнения). Затем цикл выполнения отслеживает их активность. Конечно, можно обеспечить ввод данных из других потоков и процессов, но ввод будет обрабатываться циклом выполнения, который отслеживает эти источники в потоке, выполняющем цикл выполнения.
- означает ли это, что иногда я могу использовать цикл запуска для блокировки потока на время
действительно. Фактически цикл выполнения будет "оставаться" в обработчике событий до тех пор, пока этот обработчик событий не вернется. Вы можете увидеть это в любом приложении достаточно просто. Установите обработчик для любого действия ввода-вывода (например, нажмите кнопку), который спит. Вы заблокируете основной цикл выполнения (и весь пользовательский интерфейс), пока этот метод не завершится.
то же самое относится к любой петля.
Я предлагаю вам прочитать следующую документацию на выполнения петли:
https://developer.apple.com/documentation/foundation/nsrunloop
и как они используются в рамках темы:
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 to false.
аналогично вы можете использовать их в потоках.
надеюсь, это поможет вам.
циклы выполнения-это то, что отделяет интерактивные приложения с инструменты.
- инструменты командной строки запускаются с параметрами, выполняют их команду, затем выходят.
- интерактивные приложения ждать для ввода пользователем, реагировать, а затем возобновить ожидание.
С здесь
они позволяют вам ждать, пока пользователь нажмите и ответьте соответственно, подождите, пока вы получите completionHandler и примените его результаты, подождите, пока вы получите таймер и выполните функцию. Если у вас нет runloop, вы не можете слушать/ждать пользовательских нажатий, вы не можете ждать, пока произойдет сетевой вызов, вы не можете быть разбужены за x минут.
и с комментарий:
фоновые потоки не имеют собственных runloops, но вы можете просто добавить один. Е. Г. AFNetworking 2.x сделал это. Это была испытанная и истинная техника для NSURLConnection или NSTimer в фоновых потоках, но мы этого не делаем мы гораздо больше, так как новые API устраняют необходимость делать это. Но похоже, что URLSession делает, например,вот простой запрос, работающего [см. левую панель изображения] обработчики завершения в главной очереди, и вы можете видеть, что он имеет запуск петля На фоновом потоке
циклы выполнения являются частью фундаментальной инфраструктуры, связанной с потоками. Цикл выполнения-это цикл обработки событий, используемый для планирования работы и координации приема входящих событий. Цель цикла выполнения - сохранить поток занятым, когда есть работа, и перевести поток в спящий режим, когда его нет.
наиболее важной особенностью CFRunLoop является CFRunLoopModes. CFRunLoop работает с системой "Run Loop Sources". Источники регистрируются в цикле выполнения для одного или нескольких режимов, а сам цикл выполнения выполняется в заданном режиме. Когда событие поступает в источник, оно обрабатывается циклом выполнения, только если исходный режим соответствует текущему режиму цикла выполнения.