objective c - Mantenga NSThread vivo y ejecute NSRunLoop en él
objective-c cocoa (2)
Esta pieza de código debería forzar al hilo a esperar por siempre.
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''s value
Así que estoy empezando un nuevo NSThread que quiero poder usar más tarde llamando a performSelector:onThread:...
Por lo que yo entiendo, llamar a los métodos que agregan esa llamada al runloop en ese hilo, por lo que en su próxima iteración hará aparecer todas estas llamadas y luego las llamará hasta que no quede nada para llamar. Así que necesito este tipo de funcionalidad, un hilo inactivo listo para el trabajo al que puedo recurrir. Mi código actual se ve así:
- (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];
}
Pero el hilo no se mantiene vivo, y el performSelector: onThread no hace nada. ¿Cómo hago para esto de la manera correcta?
Un bucle de ejecución requiere al menos una "fuente de entrada" para ejecutarse. El bucle de ejecución principal lo hace, pero tiene que agregar una fuente manualmente para obtener un método de ejecución del bucle de ejecución secundario para hacer cualquier cosa. Hay algo de documentación sobre esto here .
Una forma ingenua de hacer que esto funcione sería poner [[NSRunLoop currentRunLoop] run]
en un bucle infinito; cuando haya algo que hacer, lo hará, y volverá inmediatamente de lo contrario. El problema es que el subproceso tomará una cantidad decente de tiempo de procesador simplemente esperando que ocurra algo.
Otra solución es instalar un NSTimer en este bucle de ejecución para mantenerlo vivo.
Pero, si es posible, debe usar un mecanismo diseñado para este tipo de cosas. Si es posible, puede usar NSOperationQueue
para operaciones en segundo plano.