OperationQueue — qué es, Operation y gestión de tareas

Autor: IT Sectr Publicado: 2026-03-16 Tiempo de lectura: 8 min

OperationQueue es una cola de tareas de alto nivel en iOS y macOS construida sobre Grand Central Dispatch. Según Apple Developer Documentation, 2026, OperationQueue gestiona instancias de Operation — objetos que encapsulan una unidad de trabajo. A diferencia de DispatchQueue, OperationQueue soporta dependencias entre operaciones, prioridades, observación KVO y cancelación de tareas en ejecución. OperationQueue administra automáticamente un grupo de hilos, distribuyendo las operaciones entre los recursos disponibles del sistema.

Puntos Clave

  • OperationQueue — una cola de alto nivel con soporte para dependencias entre operaciones
  • Operation — una clase abstracta para encapsular una unidad de trabajo con estado
  • BlockOperation — una implementación simplificada de Operation para un solo bloque de código
  • Dependencias definen el orden de ejecución: la operación B se ejecuta después de A
  • Cancelación de operaciones se soporta a través de la propiedad isCancelled compatible con KVO

¿Qué es OperationQueue y Operation?

OperationQueue es una clase del framework Foundation que gestiona la ejecución de objetos Operation. A diferencia de DispatchQueue, OperationQueue no requiere especificar explícitamente el modo serial o concurrente — la cantidad de operaciones que se ejecutan simultáneamente se controla mediante la propiedad maxConcurrentOperationCount. Un valor de 1 convierte la cola en secuencial, cualquier otro valor la hace concurrente.

Operation es una clase abstracta que representa una unidad de trabajo. Cada operación tiene un estado: ready, executing, finished o cancelled. Los estados son compatibles con KVO (Key-Value Observing), lo que permite reaccionar a cambios — por ejemplo, actualizar la interfaz cuando una operación finaliza. Operation gestiona automáticamente las banderas isExecuting e isFinished.

Según Apple (2026), OperationQueue utiliza GCD internamente pero añade funcionalidades no disponibles en DispatchQueue: dependencias, prioridades y cancelación de operaciones. Si la aplicación pasa a segundo plano, OperationQueue suspende la ejecución y la reanuda al regresar. OperationQueue también considera automáticamente la cantidad de núcleos de CPU y selecciona el número óptimo de hilos.

Ciclo de Vida de una Operation

Cada operación pasa por cuatro estados: pending (pendiente), ready (lista), executing (en ejecución) y finished (finalizada). El estado cancelled puede ocurrir en cualquier etapa antes de la finalización. Las transiciones de estado se rastrean mediante KVO — esta es la base para actualizaciones reactivas de la interfaz. OperationQueue elimina automáticamente las operaciones completadas de la cola y notifica a las operaciones dependientes que su prerrequisito se ha cumplido, activando su ejecución.

Operation y BlockOperation: Implementación de Tareas

Operation es una clase abstracta que requiere sobrescribir el método main() o start(). El código de la tarea se coloca en el método main(), y los estados isExecuting e isFinished se gestionan automáticamente. Para operaciones asíncronas, es necesario sobrescribir start() y gestionar manualmente las banderas de estado.

BlockOperation es una implementación concreta de Operation que ejecuta uno o más bloques de código. BlockOperation se vuelve concurrente si se añaden varios bloques mediante addExecutionBlock(). La operación finaliza solo después de que todos los bloques añadidos se hayan ejecutado. BlockOperation es una alternativa conveniente para tareas simples sin herencia.

CaracterísticaOperationBlockOperation
Tipo de ClaseAbstractaConcreta
HerenciaRequeridaNo requerida
AsincroníaGestión manual de KVOAutomática
Bloques de CódigoUno en main()Uno o varios
UsoTareas complejas con estadoTareas simples de una sola vez
Adecuado paraDependencias, cancelación, progresoBloques rápidos, finalización
MemoriaMayor debido a KVO y estadoMínima, ligera

Creación de una Operation Personalizada

Para crear una operación personalizada, herede de Operation y sobrescriba main(). Dentro, verifique la bandera isCancelled antes de operaciones costosas para garantizar una cancelación rápida. Esto es crítico para descargar archivos grandes o procesar lotes de datos. Elegir entre Operation y BlockOperation depende de la complejidad de la tarea: para acciones simples de una sola vez, BlockOperation es suficiente; para lógica reutilizable con estado, herede de Operation.

Dependencias y Prioridades de Operaciones

Las dependencias son la ventaja clave de OperationQueue sobre DispatchQueue. El método addDependency(_:) especifica que la operación B se ejecuta solo después de que la operación A finalice. Las dependencias forman un grafo acíclico dirigido (DAG): si se añade una dependencia cíclica, la cola la ignora y las operaciones no se inician.

La prioridad de una operación se establece mediante la propiedad queuePriority con valores: .veryLow, .low, .normal, .high, .veryHigh. La prioridad afecta el orden de inicio entre las operaciones listas, pero no anula las dependencias. OperationQueue primero resuelve las dependencias, luego aplica la prioridad entre las operaciones disponibles.

Ejemplo Práctico de Dependencias

Un escenario típico es la carga de datos de perfil: primero cargar el usuario, luego basándose en su id cargar amigos y publicaciones. Establecer una dependencia entre cargar el usuario y cargar amigos garantiza el orden correcto sin manejadores de finalización anidados.

Limitando la Concurrente

La propiedad maxConcurrentOperationCount limita la cantidad de operaciones que se ejecutan simultáneamente. Un valor de 1 crea una cola secuencial, el valor predeterminado (NSOperationQueueDefaultMaxConcurrentOperationCount) es óptimo para el sistema y depende de la carga actual del dispositivo. Una configuración adecuada de este parámetro previene el consumo excesivo de recursos: para cargar imágenes, 4–6 operaciones concurrentes son suficientes; para tareas intensivas de CPU, use la cantidad de núcleos del procesador.

OperationQueue vs DispatchQueue: Comparación

Elegir entre OperationQueue y DispatchQueue depende de la complejidad de la tarea. DispatchQueue es una herramienta ligera para llamadas asíncronas simples. OperationQueue es una solución más pesada para escenarios complejos con muchas tareas interrelacionadas. Apple recomienda comenzar con DispatchQueue y cambiar a OperationQueue solo cuando se necesiten dependencias o cancelación. Para la mayoría de los proyectos iOS, una combinación de ambas herramientas proporciona un equilibrio óptimo entre rendimiento y flexibilidad.

  • DispatchQueue — ligera, rápida, sin sobrecarga de objetos Operation
  • OperationQueue — soporta dependencias, cancelación, KVO y prioridades
  • DispatchQueue — ideal para tareas async/asyncAfter simples y sincronización serial
  • OperationQueue — indispensable para algoritmos paso a paso con etapas secuenciales
  • DispatchQueue — se integra con Swift Concurrency (async/await) mediante Continuation

Según Ray Wenderlich (2025), en proyectos iOS grandes, OperationQueue se utiliza para cargar contenido con progreso y cancelación, mientras que DispatchQueue se usa para todas las demás operaciones asíncronas. La proporción es aproximadamente 20 a 80 a favor de DispatchQueue.

Ejemplos de Código con OperationQueue en Swift

Veamos tres ejemplos: un BlockOperation simple, una Operation personalizada con dependencias y una operación cancelable para carga de datos.

BlockOperation con Finalización

El caso más simple — ejecutar un bloque en OperationQueue y manejar el resultado mediante completionBlock. Cada Operation tiene una propiedad completionBlock incorporada, que se llama después de que main() finaliza.

swift
let queue = OperationQueue()
let operation = BlockOperation()
operation.addExecutionBlock {
    let data = NetworkService.fetchData()
    OperationQueue.main.addOperation {
        self.updateUI(data)
    }
}
queue.addOperation(operation)

Dependencias Entre Operaciones

La dependencia garantiza que parseOperation se inicie solo después de que downloadOperation finalice. Esto elimina la necesidad de callbacks anidados.

swift
let download = BlockOperation { self.downloadJSON() }
let parse = BlockOperation { self.parseJSON() }
parse.addDependency(download)

let queue = OperationQueue()
queue.addOperations([download, parse], waitUntilFinished: false)

Operación Personalizada Cancelable

Sobrescriba main() con verificaciones periódicas de isCancelled. Esto permite que la operación se detenga inmediatamente al cancelarse, sin esperar a que finalice una operación costosa.

swift
class ImageLoadOperation: Operation {
    override func main() {
        guard !self.isCancelled else { return }
        let image = self.downloadImage()
        guard !self.isCancelled else { return }
        OperationQueue.main.addOperation { self.display(image) }
    }
}

Cancelación de Operaciones y Observación KVO

La cancelación de una operación establece la bandera isCancelled en true, pero no detiene un método main() que ya se está ejecutando. El código dentro de main() debe verificar isCancelled por sí mismo y terminar cuando sea necesario. Esta es una decisión arquitectónica de Apple — que permite al desarrollador liberar recursos correctamente al cancelar.

La observación KVO de las propiedades isFinished e isExecuting permite reaccionar a la finalización de operaciones sin callbacks explícitos. OperationQueue elimina automáticamente las operaciones completadas de la cola, pero permanecen en memoria mientras haya referencias fuertes a ellas. KVO es la base para integrar OperationQueue con frameworks reactivos como RxSwift o Combine.

Manejo de Cancelación mediante KVO

Suscribirse a isCancelled mediante KVO permite actualizar la interfaz al cancelar una operación — por ejemplo, mostrar un marcador de posición en lugar de una descarga cancelada. La propiedad isCancelled es compatible con KVO, lo que la hace conveniente para pipelines reactivos.

Mejores Prácticas para Trabajar con OperationQueue

No cree grandes cantidades de operaciones — cada Operation es un objeto separado en memoria. Si una tarea es corta y no requiere dependencias, use DispatchQueue directamente. OperationQueue está justificada para escenarios complejos con dependencias explícitas, cancelación y monitoreo de progreso.

Verifique isCancelled antes de operaciones costosas dentro del método main(). En casos de descarga de archivos o procesamiento de imágenes, verificar después de cada paso significativo garantiza una respuesta rápida a la cancelación. Use if isCancelled { return } al inicio de main() y después de cada operación importante.

Gestione completionBlock adecuadamente. La propiedad completionBlock de una operación se llama después de que main() finaliza, incluso si la operación fue cancelada. Verifique isCancelled dentro de completionBlock para evitar actualizar la interfaz con datos erróneos. OperationQueue.main es una cola segura para hilos para operaciones de interfaz, similar a DispatchQueue.main.

Evite dependencias cíclicas — hacen que ninguna de las operaciones en el ciclo se inicie. OperationQueue no detecta ciclos automáticamente: si A depende de B y B depende de A, ambas permanecerán en estado ready para siempre. Planifique el grafo de dependencias con anticipación.

Preguntas Frecuentes

¿En qué se diferencia OperationQueue de DispatchQueue?

OperationQueue está construida sobre GCD y añade dependencias, prioridades, KVO y cancelación de operaciones. DispatchQueue es una herramienta más ligera para tareas asíncronas simples sin estas capacidades.

¿Cómo hago que la cola sea secuencial?

Establezca la propiedad maxConcurrentOperationCount en 1. Esto convierte OperationQueue en una cola secuencial conservando todas las ventajas — dependencias, prioridades y cancelación.

¿Se puede cancelar una operación en ejecución?

El método cancel() establece la bandera isCancelled pero no detiene el método main() en ejecución. El código de la operación debe verificar isCancelled por sí mismo y terminar. La cancelación solo funciona para operaciones pendientes y listas.

¿Cuándo debo usar Operation en lugar de BlockOperation?

Debe heredar de Operation cuando necesite gestión de estado, asincronía o reutilización de lógica. BlockOperation es adecuado para tareas simples de una sola vez sin herencia.

¿OperationQueue bloquea el hilo principal?

No, a menos que llame a waitUntilFinished con el parámetro true en el hilo principal. Las operaciones se ejecutan en hilos de fondo por defecto y los resultados se devuelven mediante OperationQueue.main.

Resumen

  • OperationQueue — una cola de alto nivel con dependencias, prioridades y cancelación de operaciones
  • Operation — una clase abstracta para encapsular trabajo con estado compatible con KVO
  • BlockOperation — una implementación simplificada para uno o más bloques de código
  • Dependencias definen el orden de ejecución entre operaciones mediante un grafo sin ciclos
  • Cancelación requiere verificación manual de isCancelled dentro del método main() de la operación
  • maxConcurrentOperationCount = 1 convierte la cola en modo secuencial
  • OperationQueue vs DispatchQueue — elija OperationQueue solo cuando necesite dependencias o KVO

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.

Discutir el proyecto

Lea también