DispatchQueue es una cola fundamental de Grand Central Dispatch (GCD) para gestionar tareas asíncronas en iOS y macOS. Según la Apple Developer Documentation, 2026, DispatchQueue abstrae la gestión de hilos del desarrollador a través de colas serial y concurrente. GCD distribuye automáticamente las tareas al pool de hilos del sistema, eliminando la necesidad de crear y destruir hilos manualmente.
Puntos clave
DispatchQueue es un objeto del framework Grand Central Dispatch (GCD) que gestiona la ejecución de tareas en colas de hilos del sistema o personalizadas. Grand Central Dispatch es una biblioteca de bajo nivel de Apple, disponible desde iOS 4 y macOS 10.6, que abstrae completamente la gestión de hilos del desarrollador. GCD utiliza el pool de hilos del sistema operativo y escala automáticamente el número de hilos según la carga del dispositivo.
El desarrollador no necesita crear y destruir hilos manualmente — GCD se encarga de esta tarea, proporcionando una API simple a través de DispatchQueue. Una tarea en forma de closure se envía a una cola mediante los métodos sync o async. En el primer caso, el hilo llamante se bloquea hasta que la tarea finaliza; en el segundo, la ejecución continúa inmediatamente.
Según Apple (2026), GCD utiliza un pool de hilos del sistema que se adapta al número de núcleos y a la carga actual de la CPU. Una cola concurrente no crea un nuevo hilo para cada tarea — GCD reutiliza hilos del pool, minimizando la sobrecarga de creación de hilos.
Grand Central Dispatch consta de tres componentes clave: colas (DispatchQueue), grupos (DispatchGroup) y semáforos (DispatchSemaphore). La cola es el elemento principal que acepta tareas en forma de bloques de código. DispatchGroup sincroniza la ejecución de múltiples tareas, mientras que DispatchSemaphore limita el acceso a un recurso compartido a un número específico de hilos.
Cada cola de GCD está asociada a una clase QoS (Quality of Service) específica, que informa al sistema sobre la importancia de la tarea. El sistema utiliza QoS para distribuir el tiempo de CPU entre las colas, dando prioridad a las tareas más críticas — como la actualización de la UI o el manejo de toques del usuario.
Una cola serial ejecuta tareas estrictamente en secuencia, una tras otra. Si se colocan tres tareas en una cola serial, la segunda comienza solo después de que la primera haya finalizado por completo. Las colas seriales se utilizan para sincronizar el acceso a recursos compartidos — por ejemplo, un array modificado desde múltiples partes del código.
Una cola concurrente ejecuta varias tareas simultáneamente, distribuyéndolas entre los hilos disponibles del pool del sistema. Las tareas en una cola concurrente se inician en orden FIFO, pero se completan en orden arbitrario si sus tiempos de ejecución difieren. Una cola concurrente no garantiza el orden de finalización — solo el orden de inicio.
| Parámetro | Cola serial | Cola concurrente |
|---|---|---|
| Orden de ejecución | Estrictamente secuencial | Paralelo |
| Número de hilos | Uno | Varios del pool de GCD |
| Aplicación | Protección de recursos compartidos | Cálculos independientes |
| Cola principal | Sí (hilo principal) | No |
| Riesgo de deadlock | Alto al hacer sync en la misma cola | Bajo |
Una cola serial es ideal para tareas que modifican estado compartido — escribir en un archivo, actualizar un modelo de datos o trabajar con Core Data. El uso de una cola serial garantiza que dos fragmentos de código no modifiquen los mismos datos simultáneamente, eliminando condiciones de carrera sin bloqueos adicionales.
Una cola concurrente es adecuada para tareas que no dependen entre sí: cargar múltiples imágenes, solicitudes de red paralelas o procesamiento por lotes de datos. GCD decide automáticamente cuántas tareas ejecutar simultáneamente según el número de núcleos de la CPU y la carga actual del sistema.
QoS (Quality of Service) es un mecanismo de GCD que informa al sistema operativo sobre la importancia y urgencia de una tarea. El sistema utiliza QoS para la planificación de hilos: las tareas con QoS más alto reciben más tiempo de CPU y se inician antes. El valor de QoS se pasa al crear una cola o al enviar una tarea específica.
GCD tiene cinco clases de QoS disponibles. .userInteractive — la prioridad más alta para tareas relacionadas con la UI. .userInitiated — para tareas iniciadas por el usuario. .utility — para tareas en segundo plano que muestran progreso. .background — para tareas invisibles para el usuario. .default — un nivel intermedio entre userInitiated y utility, usado por defecto.
Según Apple (2026), la selección incorrecta de QoS es una de las causas comunes de problemas de rendimiento. Ejecutar una descarga en segundo plano con QoS .userInteractive consume recursos de la UI, causando micro-lags en las animaciones. Se recomienda elegir el QoS más bajo que aún proporcione un tiempo de ejecución aceptable.
Al cargar una imagen para mostrarla inmediatamente, use .userInitiated — el usuario espera el resultado. Para precargar la siguiente pantalla, .utility es suficiente. La sincronización en segundo plano con el servidor se ejecuta con .background, minimizando el impacto en las tareas activas.
DispatchGroup permite rastrear la finalización de un grupo de tareas. Cuando todas las tareas del grupo se completan, GCD llama a un manejador notify en la cola especificada. Esto es especialmente útil al cargar múltiples recursos independientes — datos de perfil, lista de amigos y configuración — donde la interfaz debe actualizarse solo después de recibir todos los datos.
DispatchGroup admite una llamada síncrona wait(), que bloquea el hilo actual hasta que todas las tareas se completen. Esto es conveniente cuando el código no puede continuar sin los resultados del grupo. La variante asíncrona notify() llama a un closure en la cola especificada después de que todas las tareas finalicen, sin bloquear el hilo llamante.
DispatchSemaphore controla el acceso a un recurso limitando el número de accesos concurrentes. Un semáforo con valor inicial 3 permite no más de tres tareas en paralelo. Llamar a wait() disminuye el contador, signal() lo incrementa. Si el contador llega a cero, el hilo se bloquea hasta que un recurso esté disponible.
Veamos tres ejemplos prácticos de uso de DispatchQueue en Swift. El primero demuestra una llamada async básica con retorno al hilo principal, el segundo muestra la sincronización mediante una cola serial, y el tercero utiliza DispatchGroup para solicitudes paralelas.
DispatchQueue.main es la cola serial del hilo principal, destinada exclusivamente a operaciones de UI. Úsela siempre para actualizar la interfaz después de completar el trabajo en segundo plano.
let queue = DispatchQueue.global(qos: .userInitiated)
queue.async {
let data = self.fetchData()
DispatchQueue.main.async {
self.updateUI(with: data)
}
}
Crear una cola serial personalizada con un identificador único sincroniza el acceso a un array mutable. Todas las operaciones de lectura y escritura pasan por una sola cola, eliminando condiciones de carrera.
let serialQueue = DispatchQueue(label: "com.app.items")
var items: [Int] = []
serialQueue.async {
items.append(1)
}
serialQueue.async {
let last = items.last
DispatchQueue.main.async {
print("Last item: \(last)")
}
}
DispatchGroup permite lanzar múltiples tareas en una cola concurrente y recibir una notificación cuando todas se completen. Esto es útil al cargar datos para una pantalla de perfil.
let group = DispatchGroup()
let worker = DispatchQueue.global()
worker.async(group: group) { self.loadProfile() }
worker.async(group: group) { self.loadFriends() }
worker.async(group: group) { self.loadSettings() }
group.notify(queue: DispatchQueue.main) {
self.showCompleteUI()
}
El deadlock al llamar a sync en una cola serial es el error más común. Si una tarea en una cola serial llama a queue.sync en la misma cola, el hilo se bloquea para siempre. La cola espera que la tarea actual finalice, y la tarea espera que la llamada sync termine — un bloqueo mutuo clásico.
Todas las operaciones con UIKit deben realizarse en el hilo principal. Xcode detecta estos errores en modo Debug mediante el Main Thread Checker. En compilaciones Release, provocan un comportamiento impredecible: las animaciones no se inician, la UI no se actualiza y pueden ocurrir crashes.
Crear cientos de colas personalizadas en lugar de usar colas globales es un antipatrón. Cada cola consume recursos del sistema. Para la mayoría de las tareas, las colas concurrentes globales con diferentes niveles de QoS y una o dos colas seriales para sincronizar datos compartidos son suficientes.
Al ejecutar tareas de bucle con uso intensivo de recursos en una cola en segundo plano sin autoreleasepool, la memoria crece hasta que todo el bucle finaliza. ARC solo libera objetos al salir del autorelease pool. Envuelva las iteraciones del bucle en autoreleasepool { } para una liberación oportuna de memoria.
Preguntas frecuentes
OperationQueue está construida sobre GCD pero proporciona una API de más alto nivel con dependencias de operaciones, KVO y soporte de cancelación. DispatchQueue es una cola de bajo nivel para tareas async simples sin gestión de dependencias.
GCD no admite la detención de una tarea en ejecución. El método suspend() solo pausa las tareas nuevas; la actual se ejecuta hasta el final. La cancelación requiere una verificación manual de bandera dentro del código de la tarea.
Para una solicitud principal con visualización inmediata del resultado — .userInitiated. Para precarga de datos — .utility. Para sincronización en segundo plano — .background.
GCD no fija el número de hilos. El pool de hilos se escala dinámicamente según la carga, considerando los núcleos de la CPU, la carga actual y el QoS de cada tarea. El número máximo está limitado por el sistema.
UIKit no es thread-safe — todas sus clases deben llamarse solo desde el hilo principal. La violación causa comportamiento impredecible, actualizaciones perdidas y crashes en Producción.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también