Trabajo con colas de tareas en Swift: GCD y OperationQueue

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿Por qué necesitamos colas de tareas en Swift?

En el desarrollo moderno para iOS y macOS, el rendimiento de una aplicación depende directamente de qué tan eficientemente gestionas los hilos. Las operaciones largas —cargar datos de la red, procesar imágenes, trabajar con la base de datos— no deben bloquear el hilo principal (Main Thread), que es responsable de la interfaz. Si el hilo principal está ocupado, el usuario ve una pantalla "congelada" y el sistema puede cerrar la aplicación forzosamente.

Las colas de tareas (Task Queues) resuelven este problema. Permiten ejecutar código de forma asíncrona, paralela o secuencial, sin bloquear la UI. En Swift, hay tres herramientas principales para esto: Grand Central Dispatch (GCD), OperationQueue y el modelo moderno async/await (Swift Concurrency). En este artículo, las analizaremos con ejemplos prácticos y determinaremos cuándo usar cada una.



1. Grand Central Dispatch (GCD): el enfoque clásico

GCD es una biblioteca de bajo nivel en C que gestiona un grupo de hilos. En Swift, es fácil trabajar con ella a través de colas globales (DispatchQueue).



1.1. Tipos principales de colas en GCD

  • Main Queue — cola secuencial del hilo principal. Se usa para actualizar la UI.
  • Global Queues — colas paralelas con diferente prioridad (QoS: .userInteractive, .userInitiated, .utility, .background).
  • Custom Queues — colas creadas por ti (pueden ser secuenciales o paralelas).


1.2. Ejemplo: cargar datos en segundo plano y actualizar la UI

Supongamos que necesitamos cargar un JSON desde un servidor remoto y mostrar el resultado en una tabla.

DispatchQueue.global(qos: .userInitiated).async {    // 1. Trabajo en segundo plano: carga de datos    guard let url = URL(string: "https://api.example.com/data") else { return }    let data = try? Data(contentsOf: url)        // 2. Volvemos al hilo principal para actualizar la UI    DispatchQueue.main.async {        // Actualizamos el modelo de datos o la tabla        self.tableView.reloadData()    }}


1.3. Uso de DispatchGroup para sincronización

Cuando necesitas ejecutar varias tareas paralelas y esperar a que todas terminen, usa DispatchGroup.

let group = DispatchGroup()var images: [UIImage] = []

for url in imageURLs { group.enter() DispatchQueue.global().async { if let data = try? Data(contentsOf: url), let image = UIImage(data: data) { images.append(image) } group.leave() }}

group.notify(queue: .main) { print("Todas las imágenes cargadas: \\(images.count)") // Actualizamos la UI}


2. OperationQueue: un nivel de abstracción más alto

OperationQueue está construida sobre GCD, pero ofrece capacidades adicionales: cancelación de tareas, dependencias entre operaciones, control del número máximo de operaciones paralelas.



2.1. Creación y ejecución de operaciones

Las operaciones se pueden crear mediante BlockOperation o heredando de Operation.

let queue = OperationQueue()queue.maxConcurrentOperationCount = 2 // Limitamos a 2 tareas paralelas

let operation1 = BlockOperation { print("Operación 1 iniciada") sleep(2) print("Operación 1 completada")}

let operation2 = BlockOperation { print("Operación 2 iniciada") sleep(1) print("Operación 2 completada")}

// Establecemos una dependencia: operation2 comenzará solo después de operation1operation2.addDependency(operation1)

queue.addOperations([operation1, operation2], waitUntilFinished: false)


2.2. Cancelación de operaciones

A diferencia de GCD, las operaciones se pueden cancelar. Esto es crítico si el usuario sale de la pantalla, pero

Blogs

Book Recommendations