Подтвердить что ты не робот

Держите NSThread в живых и запустите NSRunLoop.

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

   - (void)doInitialize
   {
       mThread =  [[NSThread alloc] initWithTarget:self selector:@selector(runThread) object:nil];
       [mthread start];
   }

   - (void)runThread
   {
       NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];

       // From what I understand from the Google machine is that this call should start the
       // runloop on this thread, but it DOESN'T. The thread dies and is un-callable
       [[NSRunLoop currentRunLoop] run];

       [pool drain];
   }

   - (void)scheduleSomethingOnThread
   {
       [self performSelector:@selector(hardWork) onThread:mThread withObject:nil waitUntilDone:NO];
   }

Но нить не сохраняется в живых, а performSelector: onThread ничего не делает. Как мне это сделать правильно?

4b9b3361

Ответ 1

Для цикла запуска требуется, по крайней мере, один "входной источник" для запуска. Основной цикл запуска выполняется, но вам нужно добавить источник вручную, чтобы получить метод второго цикла -run, чтобы сделать что-либо. Там есть документация по этому здесь.

Один наивный способ заставить это работать - это просто положить [[NSRunLoop currentRunLoop] run] в бесконечный цикл; когда есть что-то делать, он это сделает и немедленно вернется. Проблема в том, что поток займет приличное количество процессорного времени, просто ожидая чего-то.

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

Но, если это возможно, вы должны использовать механизм, предназначенный для такого рода вещей. Если возможно, вы можете использовать NSOperationQueue для фоновых операций.

Ответ 2

этот кусок кода должен заставить поток ждать вечно

BOOL shouldKeepRunning = YES;        // global
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; // adding some input source, that is required for runLoop to runing
while (shouldKeepRunning && [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]); // starting infinite loop which can be stopped by changing the shouldKeepRunning value