Concurrencia y multihilo en Swift: guía completa

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 a la concurrencia y el multihilo en Swift

Las aplicaciones modernas de iOS y macOS requieren cada vez más la ejecución de múltiples tareas simultáneamente. Ya sea la descarga de datos desde la red, el procesamiento de imágenes o cálculos matemáticos complejos, no se puede prescindir de una gestión adecuada de los hilos. En Swift, la concurrencia y el multihilo están implementados al más alto nivel, proporcionando al desarrollador herramientas potentes y seguras.

En este artículo analizaremos tres enfoques principales: Grand Central Dispatch (GCD), OperationQueue y la moderna palabra clave async/await, introducida en Swift 5.5. Aprenderás cómo elegir correctamente entre ellos y evitar errores típicos como las condiciones de carrera (race condition) y los interbloqueos (deadlock).



Grand Central Dispatch (GCD) — el clásico del multihilo en Swift

Grand Central Dispatch (GCD) es una biblioteca de bajo nivel de Apple que gestiona un pool de hilos. El desarrollador no necesita crear y destruir hilos manualmente — GCD lo hace automáticamente, distribuyendo las tareas entre los núcleos disponibles del procesador.



Colas principales de GCD

En GCD existen dos tipos de colas: seriales (serial) y concurrentes (concurrent). Las tareas en una cola serial se ejecutan una tras otra, mientras que en una cola concurrente pueden iniciarse simultáneamente.

// Creación de una cola seriallet serialQueue = DispatchQueue(label: "com.example.serial")serialQueue.async {    print("Tarea 1")}serialQueue.async {    print("Tarea 2")}

// Creación de una cola concurrentelet concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)concurrentQueue.async { print("Tarea concurrente A")}concurrentQueue.async { print("Tarea concurrente B")}


Colas globales y QoS

GCD proporciona colas globales predefinidas con diferentes prioridades (Quality of Service). Úsalas cuando no sea necesario crear tu propia cola:

  • .userInteractive — para actualizaciones de la UI (máxima prioridad)
  • .userInitiated — para tareas iniciadas por el usuario
  • .utility — para operaciones de fondo prolongadas
  • .background — para tareas no críticas en tiempo
DispatchQueue.global(qos: .userInitiated).async {    // Trabajo pesado    let result = performComplexCalculation()    DispatchQueue.main.async {        // Volvemos al hilo principal para actualizar la UI        self.updateUI(with: result)    }}

Importante: Siempre actualiza la UI solo en el hilo principal (DispatchQueue.main). Ignorar esta regla provoca fallos impredecibles en la aplicación.



OperationQueue — gestión de dependencias de tareas

Si GCD es una «navaja suiza», OperationQueue es un planificador completo con capacidad de cancelación, priorización y creación de dependencias entre operaciones. Cada operación es una instancia de la clase Operation (o su subclase BlockOperation).



Creación y ejecución de operaciones

let operationQueue = OperationQueue()operationQueue.maxConcurrentOperationCount = 2 // Limitamos el número de operaciones concurrentes

let operation1 = BlockOperation { print("Operación 1")}let operation2 = BlockOperation { print("Operación 2")}

// Añadimos dependencia: operation2 comenzará solo después de que termine operation1operation2.addDependency(operation1)

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


Cancelación y prioridades

A diferencia de GCD, OperationQueue permite cancelar una operación específica o toda la cola:

// Cancelar una operaciónoperation1.cancel()

// Cancelar toda la colaoperationQueue.cancelAllOperations()

// Establecer prioridadoperation1.

Blogs

Book Recommendations