Concorrência e Multithreading em Swift: Guia Completo

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução à concorrência e multithreading em Swift

Os aplicativos modernos para iOS e macOS exigem cada vez mais a execução de várias tarefas simultaneamente. Seja para carregar dados da rede, processar imagens ou realizar cálculos matemáticos complexos — não é possível prescindir de um gerenciamento adequado de threads. Em Swift, a concorrência e o multithreading são implementados no mais alto nível, fornecendo ao desenvolvedor ferramentas poderosas e seguras.

Neste artigo, vamos analisar três abordagens principais: Grand Central Dispatch (GCD), OperationQueue e a moderna palavra-chave async/await, introduzida no Swift 5.5. Você aprenderá como escolher corretamente entre elas e evitar erros típicos, como race condition e deadlock.



Grand Central Dispatch (GCD) — o clássico do multithreading em Swift

Grand Central Dispatch (GCD) é uma biblioteca de baixo nível da Apple que gerencia um pool de threads. O desenvolvedor não precisa criar e destruir threads manualmente — o GCD faz isso automaticamente, distribuindo as tarefas pelos núcleos disponíveis do processador.



Filas principais do GCD

No GCD, existem dois tipos de filas: seriais (serial) e concorrentes (concurrent). As tarefas em uma fila serial são executadas uma após a outra, enquanto em uma fila concorrente podem ser iniciadas simultaneamente.

// Criando uma fila seriallet serialQueue = DispatchQueue(label: "com.example.serial")serialQueue.async {    print("Tarefa 1")}serialQueue.async {    print("Tarefa 2")}

// Criando uma fila concorrentelet concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)concurrentQueue.async { print("Tarefa concorrente A")}concurrentQueue.async { print("Tarefa concorrente B")}


Filas globais e QoS

O GCD fornece filas globais prontas com diferentes prioridades (Quality of Service). Use-as quando não for necessário criar sua própria fila:

  • .userInteractive — para atualizações de UI (prioridade máxima)
  • .userInitiated — para tarefas iniciadas pelo usuário
  • .utility — para operações longas em segundo plano
  • .background — para tarefas não críticas em relação ao tempo
DispatchQueue.global(qos: .userInitiated).async {    // Trabalho pesado    let result = performComplexCalculation()    DispatchQueue.main.async {        // Retornamos à thread principal para atualizar a UI        self.updateUI(with: result)    }}

Importante: Sempre atualize a UI apenas na thread principal (DispatchQueue.main). Ignorar esta regra leva a falhas imprevisíveis do aplicativo.



OperationQueue — gerenciamento de dependências de tarefas

Se o GCD é um "canivete suíço", o OperationQueue é um agendador completo com capacidade de cancelamento, priorização e criação de dependências entre operações. Cada operação é uma instância da classe Operation (ou sua subclasse BlockOperation).



Criação e execução de operações

let operationQueue = OperationQueue()operationQueue.maxConcurrentOperationCount = 2 // Limitando o número de operações simultâneas

let operation1 = BlockOperation { print("Operação 1")}let operation2 = BlockOperation { print("Operação 2")}

// Adicionando dependência: operation2 só começará após a conclusão de operation1operation2.addDependency(operation1)

operationQueue.addOperations([operation1, operation2], waitUntilFinished: false)


Cancelamento e prioridades

Ao contrário do GCD, o OperationQueue permite cancelar uma operação específica ou toda a fila:

// Cancelando uma operaçãooperation1.cancel()

// Cancelando toda a filaoperationQueue.cancelAllOperations()

// Definindo prioridadeoperation1.

Blogs

Book Recommendations