Как отправить селектор или блоки в NSRunLoop для выполнения?

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

Как настроить NSRunLoop на спящий режим после инициализации? После чего, как я могу сигнализировать о запуске цикла и что-то делать?

Я пробовал читать руководство по программированию потоков для iOS, но я бы хотел, чтобы не создавать классы в качестве пользовательских классов ввода и использовать что-то более легкое, например performSelector:onThread:

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

Вот что я хочу в псевдокоде:

 // Initialization Code... do { sleepUntilSignaled(); doWorkSentToThisThread(); while (!done); 

Там, где я отправляю эту работу, выполните performSelector:onThread: Было бы даже лучше, если бы я мог отправить цикл цикла блоку, например: ^{[someObj message]; [otherObj otherMsg];} ^{[someObj message]; [otherObj otherMsg];} но я был бы счастлив с performSelector так как я уверен, что это возможно без особого дополнительного кодирования.

Благодаря!

3 Solutions collect form web for “Как отправить селектор или блоки в NSRunLoop для выполнения?”

У вас есть все необходимые части в вашем вопросе. Вы начинаете свой поток и запускаете его runloop. Если вам нужен поток, чтобы что-то сделать, вы можете использовать performSelector:onThread: в основном потоке, чтобы сделать это.

Есть одна вещь с runloop, которую вы должны знать: это не будет работать, если у него нет источника ввода или таймера, подключенного к нему. Просто присоедините таймер к циклу запуска, который запускает некоторое время в отдаленном будущем, и вы все настроены.

 // Initialization code here [NSTimer scheduledTimerWithTimeInterval: FLT_MAX target: self selector: @selector(doNothing:) userInfo: nil repeats:YES]; NSRunLoop *rl = [NSRunLoop currentRunLoop]; do { [rl runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; } while (!done); 

Использование performSelector:onThread:withObject: вы также можете передать свой блок в фоновый поток. Все, что вам нужно сделать, это написать метод где-нибудь, который принимает блок как параметр и запускает его:

 @interface NSThread (sendBlockToBackground) - (void) performBlock: (void (^)())block; @end @implementation NSThread (sendBlockToBackground) - (void) performBlock: (void (^)())block; { [self performSelector: @selector(runBlock:) onThread: self withObject: block waitUntilDone: NO]; } - (void) runBlock: (void (^)())block; { block(); } @end 

Но, возможно, вы должны использовать очередь отправки вместо всего этого. Это требует меньше кода и, вероятно, также имеет меньшие накладные расходы:

 dispatch_queue_t myQueue = dispatch_queue_create( "net.example.product.queue", NULL ); dispatch_async( myQueue, ^{ // Initialization code here } ); // Submit block: dispatch_async( myQueue, ^{ [someObject someMethod: someParameter]; } ); 

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

Рассмотрим использование NSConditionLock. Он предназначен для таких задач. Представьте, что у вас есть очередь с данными. Первый поток добавляет данные в очередь, второй поток ждет данных и обрабатывает их.

 id condLock = [[NSConditionLock alloc] initWithCondition:NO_DATA]; //First thread while(true) { [condLock lock]; /* Add data to the queue. */ [condLock unlockWithCondition:HAS_DATA]; } //Second thread while (true) { [condLock lockWhenCondition:HAS_DATA]; /* Remove data from the queue. */ [condLock unlockWithCondition:(isEmpty ? NO_DATA : HAS_DATA)]; // Process the data locally. } в id condLock = [[NSConditionLock alloc] initWithCondition:NO_DATA]; //First thread while(true) { [condLock lock]; /* Add data to the queue. */ [condLock unlockWithCondition:HAS_DATA]; } //Second thread while (true) { [condLock lockWhenCondition:HAS_DATA]; /* Remove data from the queue. */ [condLock unlockWithCondition:(isEmpty ? NO_DATA : HAS_DATA)]; // Process the data locally. } 

Я думаю, вы можете использовать NSInvocationOperation с NSOperationQueue.

  • Добавление эффекта Pinch / Zoom в UIImageView внутри UIScrollView
  • Как подождать в NSThread, пока какое-то событие не произойдет в iOS?
  • как получить точный таймер в ios
  • Что делает NSRunLoop?
  • Каков наилучший способ периодического опроса данных с сервера, когда приложение активно в iOS в отдельном потоке?
  • Разница API NSRunLoop
  • Что происходит с моим NSRunLoop и таймером, когда приложение переходит в фоновый режим и возвращается?
  • iOS5 сбой во время runMode: beforeDate:
  • iOS, NSURLConnection: Делегировать обратные вызовы для разных потоков?
  • Выполнить повторение NSTimer с GCD?
  • Приложение перестает получать данные из сокета при прокрутке пользовательского интерфейса
  • PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.