Concurrencia con Grand Central Dispatch

Jan 24 2023
¿Qué es GCD? Grand Central Dispatch fue creado por Apple hace más de 10 años como una abstracción para ayudar a los desarrolladores a escribir código de subprocesos múltiples sin crear y administrar subprocesos manualmente. La simultaneidad significa que dos tareas pueden iniciarse, ejecutarse y completarse en intervalos de tiempo superpuestos.

¿Qué es GCD?

Grand Central Dispatch fue creado por Apple hace más de 10 años como una abstracción para ayudar a los desarrolladores a escribir código de subprocesos múltiples sin crear y administrar subprocesos manualmente.

La simultaneidad significa que dos tareas pueden iniciarse, ejecutarse y completarse en intervalos de tiempo superpuestos. Hay tres formas de lograr la concurrencia en iOS, subprocesos, colas de envío y colas de operaciones.

“En lugar de enhebrar directamente, usas GCD para programar tareas de trabajo y el sistema las realizará por ti, aprovechando al máximo sus recursos. GCD se encargará de crear los subprocesos necesarios y programará sus tareas en estos subprocesos, trasladando la carga de la gestión de subprocesos del desarrollador al sistema”.

La mayor ventaja de GCD es que no tiene que pensar en los recursos de hardware al escribir su código concurrente.

“Todas las colas de despacho son estructuras de datos de tipo primero en entrar, primero en salir (FIFO), por lo que las tareas siempre se inician en el mismo orden en que se agregan”.

Básicamente, hay tres formas de concurrencia en iOS:

  • hilos
  • colas de despacho
  • colas de operaciones

“La desventaja de los subprocesos es que relegan la carga de crear una solución escalable al desarrollador. Debe decidir cuántos subprocesos crear y ajustar ese número dinámicamente a medida que cambian las condiciones. Además, la aplicación asume la mayor parte de los costos asociados con la creación y el mantenimiento de los hilos que utiliza”.

NSThread* myThread = [[NSThread alloc] initWithTarget:self
                                       selector:@selector(myThreadMainMethod:)
                                       object:nil];
[myThread start];

“A DispatchQueuees una capa de abstracción en la parte superior de la cola de GCD que le permite realizar tareas de forma asíncrona y simultánea en su aplicación. Las tareas siempre se ejecutan en el orden en que se agregan a la cola”.

Cola en serie y cola concurrente

“Una cola de despacho en serie realiza solo una tarea a la vez. Las colas en serie se utilizan a menudo para sincronizar el acceso a un valor o recurso específico para evitar que se produzcan carreras de datos”.

let serialQueue = DispatchQueue(label: "serialQueue")

serialQueue.async {
    print("Task 1 started")
    // Do some work..
    print("Task 1 finished")
}
serialQueue.async {
    print("Task 2 started")
    // Do some work..
    print("Task 2 finished")
}
Task 1 started
Task 1 finished
Task 2 started
Task 2 finished

let concurrentQueue = DispatchQueue(label: "concurrentQueue", 
                                    attributes: .concurrent)

concurrentQueue.async {
    print("Task 1 started")
    // Do some work..
    print("Task 1 finished")
}
concurrentQueue.async {
    print("Task 2 started")
    // Do some work..
    print("Task 2 finished")
}
Task 1 started
Task 2 started
Task 1 finished
Task 2 finished

“Una cola de operación es el equivalente Cocoa de una cola de despacho concurrente y es implementada por la clase NSOperationQueue. A diferencia de las colas de despacho, las colas de operación no se limitan a ejecutar tareas en orden FIFO y admiten la creación de gráficos complejos de orden de ejecución para sus tareas”.

NSOperationQueue* myQueue = [[NSOperationQueue alloc] init];
[myQueue addOperation:anOperation]; 
[myQueue addOperationWithBlock:^{
   /* Do something. */
}];

La cola de envío principal es una cola en serie disponible globalmente que ejecuta tareas en el subproceso principal de la aplicación.

"Puede comenzar a hacer el trabajo pesado en una cola de fondo y volver a la cola principal cuando haya terminado".

DispatchQueue.main.async {
    self.tableView.reloadData()
}

Feliz codificación...