Introdução às filas de tarefas em Swift
Os aplicativos móveis e de desktop modernos precisam ser rápidos e responsivos. Se você executa cálculos pesados ou carrega dados da rede diretamente na thread principal, seu aplicativo irá travar e o usuário simplesmente o fechará. A solução são as filas de tarefas (queues).
Em Swift (iOS/macOS), o gerenciamento de assincronia é baseado em três tecnologias principais: Grand Central Dispatch (GCD), Operation Queue e a sintaxe moderna async/await. Neste artigo, abordaremos cada uma delas do zero, mostraremos exemplos de código e explicaremos quando usar cada uma.
1. Grand Central Dispatch (GCD) e DispatchQueue
GCD é uma biblioteca de baixo nível da Apple para gerenciar a execução paralela de código. O elemento principal é DispatchQueue. A fila executa as tarefas (closures) na ordem em que são adicionadas.
Tipos de filas
- Main Queue — fila serial da thread principal. Usada para atualizar a interface do usuário (UI).
- Global Queues — filas paralelas com diferentes prioridades (QoS:
.userInteractive,.userInitiated,.utility,.background). - Custom Queues — suas próprias filas (seriais ou paralelas).
Exemplo: executando uma tarefa em segundo plano
import Foundation
// Assincronamente na fila de segundo planoDispatchQueue.global(qos: .background).async { // Trabalho pesado (carregamento, processamento de dados) let result = performHeavyTask() // Retorna o resultado para a thread principal DispatchQueue.main.async { updateUI(with: result) }}
func performHeavyTask() -> String { Thread.sleep(forTimeInterval: 2) // simulação de trabalho return "Pronto!"}
func updateUI(with text: String) { print("UI atualizada: \\(text)")}Observe: .async não bloqueia a thread de chamada. Se precisar aguardar o resultado, use .sync (mas nunca chame .sync da thread principal — você terá um deadlock).
Exemplo: fila serial
let serialQueue = DispatchQueue(label: "com.example.serial")
serialQueue.async { print("Tarefa 1")}serialQueue.async { print("Tarefa 2")}// Saída: Tarefa 1, depois Tarefa 22. Operation Queue — uma abordagem mais flexível
OperationQueue é uma camada sobre o GCD, fornecendo uma interface orientada a objetos. Você cria uma Operation (ou BlockOperation), configura dependências e a adiciona à fila.
Vantagens sobre o GCD
- Cancelamento de tarefas (
cancel()) - Dependências entre tarefas
- Monitoramento de estado (isReady, isExecuting, isFinished)
- Número máximo de operações paralelas
Exemplo: uso básico
let operationQueue = OperationQueue()operationQueue.maxConcurrentOperationCount = 2 // no máximo 2 tarefas simultâneas
let operation1 = BlockOperation { print("Carregando dados...") Thread.sleep(forTimeInterval: 1)}
let operation2 = BlockOperation { print("Processando dados...") Thread.sleep(forTimeInterval: 1)}
// operation2 só começará após a conclusão de operation1operation2.addDependency(operation1)
operationQueue.addOperations([operation1, operation2], waitUntilFinished: false)Exemplo: cancelando uma operação
let cancelableOp = BlockOperation { if !cancelableOp.isCancelled { print("Executando trabalho importante") }}
operationQueue.addOperation(cancelableOp)
// Após algum tempo, cancelamosDispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { cancelableOp.cancel() print("Operação cancelada")}