DEV Community

GoyesDev
GoyesDev

Posted on

¿Qué es el RunLoop? ¿Y con qué se come?

Interrupción de procesador

Una interrupción es una señal emitida por hardware o software cuando un proceso o evento necesita atención inmediata. Esta alerta al procesador que un proceso de alta prioridad que requiere interrumpir al proceso en curso.

Cuando un dispositivo recibe una interrupción, el "Program Counter" (PC) se carga con la primera instrucción del "Interrupt Service Routine" (ISR). Antes de hacer el salto, se guarda la dirección de memoria que estaba ejecutando el procesador.

RunLoop

Un RunLoop es un bucle de software que se encarga de esperar eventos (inputs, timers, señales, mensajes del sistema) y los despacha a los objetos o funciones apropiadas para manejarlos.

Un RunLoop está presente en cada hilo de una aplicación de iOS/macOS.

Internamente, el RunLoop entrada en un ciclo como el siguiente:

while running {
  let event = esperarEvento()
  procesar(event)
}
Enter fullscreen mode Exit fullscreen mode

El sistema (Core Foundation, en este caso), pone el hilo a dormir mientras no haya eventos. Luego, cuando llega un evento, el sistema despierta el hilo, ejecuta el callback correspondiente y vuelve al modo de espera.

Técnicamente un RunLoop no está basado en interrupciones de hardware (como las de un procesador que despiertan al OS cuando llega una señal), sin embargo, sí depende de ellas indirectamente. A nivel de sistema operativo, ciertos eventos (e.g. la llegada de datos a un socket, un timer, o la entrada de un usuario) despiertan el hilo mediante mecanismos que, en última instancia, se apoyan en interrupciones de hardware y señales del kernel. El RunLoop simplemente usa esas notificaciones del sistema para decidir cuándo reanudar la ejecución.

Uno registra potenciales fuentes de eventos en el RunLoop apuntando al código que debería ser ejecutado cuando ocurra la interrupción. Si el RunLoop recibe una interrupción cuando ya está procesando otra interrupción, primero tiene que esperar a terminar de atender a la primera. La desventaja de esta aproximación es que si atender una interrupción implica ejecutar un bloque de código computacionalmente costoso, la aplicación puede bloquearse, en cuyo caso es mejor mover este trabajo en otro hilo.

¿Un RunLoop es lo mismo que un DispatchQueue?

Aunque DispatchQueue y RunLoop pueden parecer similares (ambos ejecutan código "en algún momento"), en realidad son capas diferentes del sistema de ejecución de Apple.

DispatchQueue es una cola FIFO donde se encolan bloques de código (closures) que se ejecutan en uno o varios hilos, de forma serial o concurrente. No podemos garantizar en qué hilo se ejecuta el código. Por otro lado, no estamos esperando eventos (interrupciones), sino que solo ejecuta tareas cuando las encolamos.

El RunLoop es un bucle de eventos que VIVE DENTRO DE UN HILO. Procesa las interrupciones y despacha eventos.

Un RunLoop y un DispatchQueue pueden coexistir y hasta colaborar, por ejemplo: El hilo principal tiene un RunLoop.main, que mantiene viva la UI. GCD puede despachar bloques (DispatchQueue.main.async) dentro de ese hilo principal. Esto significa que el bloque despachado por CGD se ejecuta cuando el RunLop está libre, entre eventos.

Analogía del mundo real

El RunLoop puede verse como un supervisor de un restaurante que lo mantiene funcionando, ordenando a los empleados qué hacer cuando recibe distintos eventos. En cambio, el DispatchQueue es un mesero que lleva al RunLoop trabajos específicos que debe hacer.


Bibliografía

Top comments (0)