ios objective-c cocoa-touch nsrunloop

ios - Comprender NSRunLoop



objective-c cocoa-touch (4)

Los bucles de ejecución son lo que separa las aplicaciones interactivas de las de línea de comandos.

  • Las herramientas de línea de comandos se inician con parámetros, ejecutan su comando y luego salen.
  • Las aplicaciones interactivas esperan la entrada del usuario, reaccionan y luego vuelven a esperar.

De here

Le permiten esperar hasta que el usuario toque y responda en consecuencia, espere hasta que obtenga un manejador de finalización y aplique sus resultados, espere hasta que obtenga un temporizador y realice una función. Si no tiene un runloop, entonces no puede escuchar / esperar los toques del usuario, no puede esperar hasta que se produzca una llamada de red, no puede despertarse en x minutos.

También de este comentario :

Los subprocesos de fondo no tienen sus propios runloops, pero solo puede agregar uno. Por ejemplo, AFNetworking 2.x lo hizo. Fue una técnica probada y verdadera para NSURLConnection o NSTimer en hilos de fondo, pero ya no lo hacemos nosotros mismos, ya que las nuevas API eliminan la necesidad de hacerlo. Pero parece que URLSession sí, por ejemplo, aquí hay una solicitud simple , ejecutando [ver el panel izquierdo de la imagen] controladores de finalización en la cola principal, y se puede ver que tiene un ciclo de ejecución en el hilo de fondo

¿Alguien puede explicar por qué es NSRunLoop ? entonces sé que NSRunLoop es algo relacionado con NSThread ¿verdad? Así que supongo que creo un hilo como

NSThread* th=[[NSThread alloc] initWithTarget:self selector:@selector(someMethod) object:nil]; [th start]; -(void) someMethod { NSLog(@"operation"); }

entonces después de esto, Thread termina su trabajo ¿verdad? ¿Por qué utilizar RunLoops o dónde usarlo? de los documentos de Apple, he leído algo, pero no está claro para mí, así que por favor explica lo más simple posible


Los bucles de ejecución son parte de la infraestructura fundamental asociada a los hilos. Un ciclo de ejecución es un ciclo de procesamiento de eventos que utiliza para programar el trabajo y coordinar la recepción de eventos entrantes. El propósito de un bucle de ejecución es mantener su hilo ocupado cuando hay trabajo por hacer y poner su hilo de dormir cuando no hay ninguno.

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW1

La característica más importante de CFRunLoop es CFRunLoopModes. CFRunLoop funciona con un sistema de "Run Loop Sources". Las fuentes se registran en un bucle de ejecución para uno o varios modos, y el bucle de ejecución se hace funcionar en un modo determinado. Cuando llega un evento a una fuente, solo lo maneja el ciclo de ejecución si el modo fuente coincide con el modo actual de ciclo de ejecución.

De aquí


Un bucle de ejecución es una abstracción que (entre otras cosas) proporciona un mecanismo para manejar las fuentes de entrada del sistema (sockets, puertos, archivos, teclado, mouse, temporizadores, etc.).

Cada NSThread tiene su propio ciclo de ejecución, al que se puede acceder a través del método CurrentRunLoop.

En general, no es necesario acceder directamente al ciclo de ejecución, aunque existen algunos componentes (de red) que pueden permitirle especificar qué ciclo de ejecución utilizará para el procesamiento de E / S.

Un ciclo de ejecución para un subproceso dado esperará hasta que una o más de sus fuentes de entrada tengan datos o eventos, luego activará los controladores de entrada apropiados para procesar cada fuente de entrada que esté "lista".

Después de hacerlo, volverá a su ciclo, procesando la entrada de varias fuentes, y "durmiendo" si no hay trabajo que hacer.

Esa es una descripción de alto nivel (tratando de evitar demasiados detalles).

EDITAR

Un intento de abordar el comentario. Lo rompí en pedazos.

  • significa que solo puedo acceder / ejecutar para ejecutar el bucle dentro del hilo, ¿verdad?

En efecto. NSRunLoop no es seguro para subprocesos y solo se debe acceder desde el contexto del subproceso que ejecuta el ciclo.

  • ¿Hay algún ejemplo simple de cómo agregar eventos para ejecutar bucle?

Si desea monitorear un puerto, simplemente agregue ese puerto al bucle de ejecución, y luego el bucle de ejecución vería ese puerto para la actividad.

- (void)addPort:(NSPort *)aPort forMode:(NSString *)mode

También puede agregar un temporizador de forma explícita con

- (void)addTimer:(NSTimer *)aTimer forMode:(NSString *)mode

  • ¿Qué significa que luego volverá a su ciclo?

El ciclo de ejecución procesará todos los eventos listos cada iteración (según su modo). Tendrá que consultar la documentación para descubrir los modos de ejecución, ya que eso está un poco fuera del alcance de una respuesta general.

  • ¿El ciclo de ejecución está inactivo cuando comienzo el hilo?

En la mayoría de las aplicaciones, el ciclo de ejecución principal se ejecutará automáticamente. Sin embargo, usted es responsable de iniciar el ciclo de ejecución y responder a los eventos entrantes para los hilos que gira.

  • ¿es posible agregar algunos eventos al bucle de ejecución de subprocesos fuera del subproceso?

No estoy seguro de lo que quieres decir aquí. No agrega eventos al ciclo de ejecución. Agrega fuentes de entrada y fuentes de temporizador (desde la secuencia que posee el ciclo de ejecución). El ciclo de ejecución luego los observa por actividad. Por supuesto, puede proporcionar datos de otros hilos y procesos, pero la entrada será procesada por el ciclo de ejecución que está monitoreando esas fuentes en el hilo que está ejecutando el ciclo de ejecución.

  • ¿Significa que a veces puedo usar ejecutar bucle para bloquear el hilo por un tiempo

En efecto. De hecho, un ciclo de ejecución se "mantendrá" en un controlador de eventos hasta que el controlador de eventos haya regresado. Puedes ver esto en cualquier aplicación lo suficiente. Instale un controlador para cualquier acción IO (por ejemplo, presionar un botón) que duerme. Bloqueará el ciclo de ejecución principal (y toda la UI) hasta que se complete ese método.

Lo mismo se aplica a cualquier ciclo de ejecución.

Le sugiero que lea la siguiente documentación sobre los bucles de ejecución:

https://developer.apple.com/documentation/foundation/nsrunloop

y cómo se usan dentro de los hilos:

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW1


Los Runloops son como una caja donde las cosas simplemente suceden.

Básicamente en Runloop, vas a procesar algunos eventos y luego regresas. O devuelve si no procesa ningún evento antes de que se agote el tiempo de espera. Puede decir que es similar a las NSURLConnections asincrónicas, procesando datos en segundo plano sin interferir con su bucle actual y, al mismo tiempo, requiere datos de forma sincrónica. Lo cual se puede hacer con la ayuda de Runloop que hace que mantenga su NSURLConnection asíncrona y proporcione datos en el momento de la llamada. Puede usar Runloop de la siguiente manera:

NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1]; while (YourBoolFlag && [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:loopUntil]) loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1];

en este Runloop se ejecutará hasta que complete algunos de sus otros trabajos y configure YourBoolFlag como falso .

Del mismo modo, puede usarlos en hilos.

Espero que esto te ayude.