Planificador de tareas Swift (iOS/macOS): GCD, OperationQueue y Timer
En el desarrollo para iOS y macOS, la gestión de tareas asíncronas, ejecuciones diferidas y la multitarea es la base del rendimiento y la capacidad de respuesta de las aplicaciones. En Swift se utilizan tres componentes clave para esto: GCD (Grand Central Dispatch), OperationQueue y Timer. En este artículo, analizaremos cada uno en detalle, mostraremos ejemplos de código y explicaremos cuándo usar cada uno.
1. Grand Central Dispatch (GCD) — DispatchQueue
GCD es una API de bajo nivel en C que Swift expone a través de DispatchQueue. Permite ejecutar tareas de forma asíncrona, en paralelo o en serie, gestionando los hilos automáticamente.
Tipos principales de colas:
- Main Queue — cola en serie, ejecuta tareas en el hilo principal (UI).
- Global Queues — colas paralelas con diferentes prioridades (background, user-initiated, utility).
- Custom Serial/Concurrent Queues — creadas por el desarrollador.
Ejemplo: carga de datos asíncrona
import Foundation
// Obtenemos una cola global en segundo planoDispatchQueue.global(qos: .background).async { // Trabajo pesado (análisis, carga) let data = try? Data(contentsOf: URL(string: "https://example.com/data.json")!) // Volvemos al hilo principal para actualizar la UI DispatchQueue.main.async { // Actualizamos la interfaz print("Datos cargados: \\(data?.count ?? 0) bytes") }}Ejecución diferida (dispatch_after)
let deadline = DispatchTime.now() + 3.0 // después de 3 segundosDispatchQueue.main.asyncAfter(deadline: deadline) { print("Han pasado 3 segundos")}Grupos de tareas (DispatchGroup)
let group = DispatchGroup()
group.enter()DispatchQueue.global().async { // Tarea 1 Thread.sleep(forTimeInterval: 2) group.leave()}
group.enter()DispatchQueue.global().async { // Tarea 2 Thread.sleep(forTimeInterval: 1) group.leave()}
// Notificación de finalización de todas las tareasgroup.notify(queue: .main) { print("Todas las tareas han finalizado")}2. OperationQueue — planificador de alto nivel
OperationQueue está construido sobre GCD, pero ofrece más flexibilidad: se pueden establecer dependencias entre operaciones, prioridades, cancelar tareas individuales y limitar el número máximo de operaciones paralelas.
Creación y ejecución de operaciones
let queue = OperationQueue()queue.maxConcurrentOperationCount = 2 // no más de 2 tareas paralelas
let operation1 = BlockOperation { print("Operación 1") Thread.sleep(forTimeInterval: 1)}
let operation2 = BlockOperation { print("Operación 2") Thread.sleep(forTimeInterval: 1)}
// Establecemos una dependencia: operation2 comenzará solo después de operation1operation2.addDependency(operation1)
queue.addOperations([operation1, operation2], waitUntilFinished: false)Cancelación de operaciones
operation1.cancel() // Cancela la operación si aún no se está ejecutando
// Verificación de cancelación dentro de la operaciónlet cancellableOp = BlockOperation { if !cancellableOp.isCancelled { print("Ejecutando") }}Características clave de OperationQueue:
- Se puede establecer
qualityOfService(prioridad). - Las operaciones pueden ser objetos
Operationcon el métodomain()sobrescrito. - Admite KVO (Key-Value Observing) para monitorear el estado.
3. Timer — para tareas periódicas y diferidas
Timer (anteriormente NSTimer) se utiliza para ejecutar código en intervalos específicos. Importante: los timers funcionan en