Concorrência e Multithreading em Swift: Técnicas Avançadas

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

Concorrência e Multithreading em Swift: Nível Avançado

Concorrência (concurrency) é um dos tópicos mais complexos e importantes no desenvolvimento iOS/macOS. Em nível avançado, o Swift oferece ferramentas poderosas: desde o clássico Grand Central Dispatch (GCD) até o modelo moderno async/await e o sistema rigoroso de Actors. Neste artigo, vamos analisar como gerenciar threads de forma eficiente, evitar condições de corrida e escrever código thread-safe.



1. Grand Central Dispatch (GCD): Trabalhando com Filas e Grupos

O GCD continua sendo a base do multithreading em Swift. No entanto, em nível avançado, é importante entender não apenas a diferença entre main e global(), mas também saber gerenciar dependências de tarefas.

Criando Filas Próprias

let serialQueue = DispatchQueue(label: "com.pythonlib.serial")let concurrentQueue = DispatchQueue(label: "com.pythonlib.concurrent", attributes: .concurrent)

serialQueue.async { print("Tarefa 1 na fila serial")}concurrentQueue.async { print("Tarefa 2 na fila concorrente")}

DispatchGroup: Sincronizando Múltiplas Tarefas

let group = DispatchGroup()let queue = DispatchQueue.global()

queue.async(group: group) { sleep(1) print("Carregando dados 1")}queue.async(group: group) { sleep(2) print("Carregando dados 2")}

group.notify(queue: DispatchQueue.main) { print("Todos os carregamentos concluídos, atualizando UI")}

Use DispatchGroup quando precisar aguardar a conclusão de várias operações paralelas (por exemplo, carregar imagens ou fazer parsing de JSON).



2. Modelo Moderno async/await e Task

A partir do Swift 5.5, a linguagem recebeu suporte nativo para assincronia através das palavras-chave async e await. Isso simplifica a leitura do código e elimina a "pirâmide de closures".

Declarando e Chamando uma Função Assíncrona

func fetchUserData() async -> String {    // Simulação de requisição de rede    try? await Task.sleep(nanoseconds: 2_000_000_000)    return "User data loaded"}

Task { let result = await fetchUserData() print(result) // Exibirá "User data loaded"}

Chamadas Paralelas com async let

func loadImage() async -> Data { return Data() }func loadMetadata() async -> String { return "meta" }

Task { async let image = loadImage() async let metadata = loadMetadata() let result = try await (image, metadata) print("Imagem: \\(result.0), metadados: \\(result.1)")}

async let permite iniciar várias tarefas assíncronas em paralelo e aguardar todas elas. Isso é mais eficiente do que chamadas sequenciais.



3. Actors: Thread-Safety em Nível de Linguagem

Actors são um novo mecanismo de proteção contra condições de corrida. Eles garantem que o acesso ao seu estado seja sincronizado automaticamente.

Definição e Uso de um Actor

actor BankAccount {    private var balance: Double = 0.0        func deposit(amount: Double) {        balance += amount        print("Saldo após depósito: \\(balance)")    }        func withdraw(amount: Double) -> Bool {        guard balance >= amount else { return false }        balance -= amount        return true    }        func getBalance() -> Double { balance }}

Task { let account = BankAccount() await account.deposit(amount: 100) let success = await account.withdraw(amount: 50) print("Saque bem-sucedido: \\(success)")}

Todos os métodos de um actor são isolados por padrão — só podem ser chamados através de await. Isso elimina a alteração acidental de dados por múltiplas threads.

Métodos Não Isolados (nonisolated)

actor Logger {    nonisolated func log(message: String) {        print("Log: \\(message)")    }}

Blogs

Book Recommendations