¿Alguien puede explicar qué es NSRunLoop
? así que, como sé, NSRunLoop
hay algo relacionado con NSThread
¿verdad? Así que suponga que creo un hilo como
NSThread* th=[[NSThread alloc] initWithTarget:self selector:@selector(someMethod) object:nil];
[th start];
-(void) someMethod
{
NSLog(@"operation");
}
así que después de que este hilo termine su trabajo, ¿verdad? ¿Por qué usar RunLoops
o dónde usar? de los documentos de Apple He leído algo pero no está claro para mí, así que explíquelo lo más simple posible
ios
objective-c
cocoa-touch
nsrunloop
taffarel
fuente
fuente
Respuestas:
Un ciclo 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 mediante el método currentRunLoop.
En general, no necesita acceder directamente al ciclo de ejecución, aunque hay algunos componentes (de red) que pueden permitirle especificar qué ciclo de ejecución utilizarán para el procesamiento de E / S.
Un bucle de ejecución para un subproceso determinado esperará hasta que una o más de sus fuentes de entrada tengan algún dato o evento, luego activará el controlador de entrada apropiado 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 por hacer.
Esa es una descripción de nivel bastante alto (tratando de evitar demasiados detalles).
EDITAR
Un intento de abordar el comentario. Lo rompí en pedazos.
En efecto. NSRunLoop no es seguro para subprocesos y solo se debe acceder a él desde el contexto del subproceso que ejecuta el bucle.
Si desea monitorear un puerto, simplemente agregaría ese puerto al bucle de ejecución, y luego el bucle de ejecución observará la actividad de ese puerto.
También puede agregar un temporizador explícitamente con
El ciclo de ejecución procesará todos los eventos listos en cada iteración (según su modo). Deberá consultar la documentación para descubrir los modos de ejecución, ya que eso está un poco más allá del alcance de una respuesta general.
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 de los hilos que gira.
No estoy seguro de lo que quiere decir aquí. No agrega eventos al ciclo de ejecución. Agrega fuentes de entrada y fuentes de temporizador (del hilo que posee el ciclo de ejecución). El bucle de carrera luego los observa para ver si hay actividad. Por supuesto, puede proporcionar entrada de datos de otros subprocesos y procesos, pero la entrada será procesada por el ciclo de ejecución que está monitoreando esas fuentes en el subproceso que está ejecutando el ciclo de ejecución.
En efecto. De hecho, un bucle de ejecución "permanecerá" en un controlador de eventos hasta que ese controlador de eventos haya regresado. Puede ver esto en cualquier aplicación de manera bastante simple. Instale un controlador para cualquier acción de E / S (por ejemplo, presionar un botón) que está inactivo. Bloqueará el ciclo de ejecución principal (y toda la interfaz de usuario) 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 ciclos de ejecución:
https://developer.apple.com/documentation/foundation/nsrunloop
y cómo se utilizan en los hilos:
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW1
fuente
performSelector:onThread:withObject:waitUntilDone:
, pase unNSThread
objeto y su selector se programará en el bucle de ejecución de ese hilo.Le permiten esperar hasta que el usuario toque y responder en consecuencia, espere hasta que obtenga un controlador 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 estar escuchando / esperando los toques del usuario, no puede esperar hasta que se produzca una llamada de red, no puede despertar en x minutos a menos que use
DispatchSourceTimer
oDispatchWorkItem
También de este comentario :
Específicamente sobre: "Los subprocesos en segundo plano no tienen sus propios ciclos de ejecución". El siguiente temporizador no se activa para un envío asíncrono :
Creo que la razón por la que el
sync
bloque también se ejecuta es porque:Los bloques de sincronización generalmente solo se ejecutan desde su cola de origen . En este ejemplo, la cola de origen es la cola principal, la cola cualquiera es la cola de destino.
Para probarlo, inicié sesión
RunLoop.current
en cada despacho.El envío de sincronización tenía el mismo bucle de ejecución que la cola principal. Mientras que RunLoop dentro del bloque asíncrono era una instancia diferente de las demás. Es posible que esté pensando cómo por qué
RunLoop.current
devuelve un valor diferente. ¿¡No es un valor compartido !? ¡Gran pregunta! Leer más:NOTA IMPORTANTE:
La propiedad de clase
current
NO es una variable global.Es contextual. Es visible solo dentro del alcance del hilo, es decir , almacenamiento local del hilo . Para obtener más información al respecto, consulte aquí .
Este es un problema conocido con los temporizadores. No tiene el mismo problema si usa
DispatchSourceTimer
fuente
RunLoops son como una caja donde las cosas simplemente suceden.
Básicamente, en un RunLoop, vas a procesar algunos eventos y luego regresas. O regrese si no procesa ningún evento antes de que se agote el tiempo de espera. Puede decirlo como similar a NSURLConnections asincrónicas, procesando datos en segundo plano sin interferir en su bucle actual y, al mismo tiempo, necesita datos sincrónicamente. Lo cual se puede hacer con la ayuda de RunLoop que hace que su asincrónico
NSURLConnection
y proporciona datos en el momento de la llamada. Puedes usar un RunLoop como este:En este RunLoop, se ejecutará hasta que complete algunos de sus otros trabajos y configure YourBoolFlag en falso .
Del mismo modo, puede usarlos en subprocesos.
Espero que esto te ayude.
fuente
De aquí
De aquí
fuente