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
```html

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



Os aplicativos modernos para iOS e macOS devem ser rápidos e responsivos. O usuário não deve esperar enquanto uma imagem é carregada ou um cálculo complexo é executado. Para isso, o Swift possui mecanismos de concorrência e multithreading. Neste artigo, vamos explorar os conceitos-chave, desde o clássico Grand Central Dispatch (GCD) até o moderno async/await do Swift Concurrency.



Concorrência (concurrency) é a capacidade de um programa executar várias tarefas simultaneamente, alternando entre elas. Multithreading é uma das implementações de concorrência, onde as tarefas são executadas em diferentes threads do sistema operacional. O Swift fornece ferramentas poderosas e seguras para trabalhar com esses conceitos.



1. Grand Central Dispatch (GCD) — a base do multithreading



Grand Central Dispatch (GCD) é uma biblioteca de baixo nível da Apple para gerenciar a execução paralela de código. Ela funciona com base em filas (dispatch queues).



Tipos de filas no GCD

  • Serial Queue (fila serial) — as tarefas são executadas uma após a outra, na ordem em que foram adicionadas.
  • Concurrent Queue (fila concorrente) — as tarefas podem ser executadas simultaneamente em diferentes threads.
  • Main Queue (fila principal) — executa tarefas na thread principal, destinada a atualizações da interface do usuário (UI).
  • Global Queues (filas globais) — filas concorrentes do sistema com diferentes prioridades (QoS).


Exemplo: executar uma tarefa em segundo plano e atualizar a UI



import UIKit

class ViewController: UIViewController { @IBOutlet weak var imageView: UIImageView!

func loadImage(from url: URL) { // Mudamos para a fila de segundo plano DispatchQueue.global(qos: .background).async { [weak self] in guard let data = try? Data(contentsOf: url), let image = UIImage(data: data) else { return } // Voltamos para a thread principal para atualizar a UI DispatchQueue.main.async { self?.imageView.image = image } } }}


Neste exemplo, baixamos a imagem em uma thread de segundo plano para não bloquear a interface e, em seguida, atualizamos a UI na thread principal.



DispatchGroup para sincronização de tarefas



DispatchGroup permite monitorar a execução de um grupo de tarefas assíncronas e executar uma ação após sua conclusão.



let group = DispatchGroup()

group.enter()fetchData1 { result in print("Dados 1 recebidos") group.leave()}

group.enter()fetchData2 { result in print("Dados 2 recebidos") group.leave()}

group.notify(queue: .main) { print("Todos os dados carregados, atualizando a UI")}


2. OperationQueue — abordagem orientada a objetos



OperationQueue é uma abstração de nível mais alto sobre o GCD. Ela trabalha com objetos Operation, que representam uma unidade de trabalho.



Vantagens da OperationQueue

  • Possibilidade de cancelar tarefas (cancel).
  • Definição de dependências entre operações (addDependency).
  • Monitoramento do estado da operação (isFinished, isExecuting, isCancelled).
  • Configuração do número máximo de operações paralelas.


Exemplo: carregar várias imagens



import UIKit

class ImageLoader { private let queue = OperationQueue() func loadImages(from urls: [URL], completion: @escaping ([UIImage]) -> Void) { var images: [UIImage] = [] let completionOperation = BlockOperation { DispatchQueue.main.async { completion(images) } } for url in urls { let o ```

Blogs

Book Recommendations