Filas de Tarefas em Swift: do GCD ao Swift Concurrency
No desenvolvimento para iOS e macOS, gerenciar a execução paralela de código é uma das tarefas principais. As filas de tarefas (queues) permitem distribuir eficientemente a carga entre threads, sem bloquear a interface do usuário. Neste guia, abordaremos três abordagens principais: o clássico Grand Central Dispatch (GCD), a abstração OperationQueue e o mecanismo moderno Swift Concurrency (async/await).
1. Grand Central Dispatch (GCD) — a base do paralelismo
GCD é uma biblioteca C de baixo nível, integrada ao Swift. Ela gerencia um pool de threads e fornece dois tipos de filas:
- Serial (sequenciais) — as tarefas são executadas uma após a outra na ordem de adição.
- Concurrent (paralelas) — as tarefas são iniciadas simultaneamente, a ordem de conclusão não é garantida.
Exemplo de criação e uso de uma fila:
import Foundation
// Criando uma fila seriallet serialQueue = DispatchQueue(label: "com.example.serial")
serialQueue.async { print("Tarefa 1 iniciada") sleep(1) print("Tarefa 1 concluída")}
serialQueue.async { print("Tarefa 2 iniciada") sleep(1) print("Tarefa 2 concluída")}
// Fila paralelalet concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)
concurrentQueue.async { print("Tarefa paralela A")}
concurrentQueue.async { print("Tarefa paralela B")}Principais recursos do GCD:
DispatchQueue.main— fila principal (thread da UI).DispatchQueue.global(qos: .userInitiated)— filas globais com prioridade (QoS).dispatchGroup— sincronização de várias tarefas.dispatchSemaphore— controle de acesso a recursos.
2. OperationQueue — abstração orientada a objetos
OperationQueue é construída sobre o GCD, mas fornece uma API de nível mais alto. Principais vantagens:
- Gerenciamento de dependências entre operações.
- Cancelamento de tarefas (cancel).
- Monitoramento de estado (isFinished, isExecuting).
- Número máximo de operações paralelas.
Exemplo usando BlockOperation:
import Foundation
let operationQueue = OperationQueue()operationQueue.maxConcurrentOperationCount = 2
let operation1 = BlockOperation { print("Operação 1: carregando dados") sleep(2) print("Operação 1 concluída")}
let operation2 = BlockOperation { print("Operação 2: processando") sleep(1) print("Operação 2 concluída")}
// Definindo dependência: a operação 2 só iniciará após a conclusão da operação 1operation2.addDependency(operation1)
operationQueue.addOperations([operation1, operation2], waitUntilFinished: false)
// Cancelando uma operaçãooperation1.cancel()Quando usar OperationQueue:
- Cadeias complexas de tarefas com dependências.
- Necessidade de controle refinado (pausa, cancelamento).
- Trabalho com KVO (Key-Value Observing) para monitoramento.
3. Swift Concurrency — abordagem moderna (iOS 13+, macOS 10.15+)
A partir do Swift 5.5, a Apple introduziu suporte nativo à programação assíncrona através de async/await, Task e TaskGroup. Esta é uma forma mais segura e legível de trabalhar com paralelismo.
Exemplo básico:
import Foundation
func fetchUserData() async -> String { // Simulação de requisição de rede try? await Task.sleep(nanoseconds: 2 * 1_000_000_000) return "Dados do usuário carregados"}
func processData()