Lição: 50: Introdução à Concorrência em Swift
A concorrência é um conceito essencial na programação moderna, especialmente quando se trata de tornar as aplicações responsivas e eficientes. Nesta aula, vamos explorar os fundamentos da concorrência em Swift, demonstrando como realizar operações assíncronas e gerenciar tarefas concorrentes de forma eficaz.
O que é Concorrência?
Concorrência permite que várias tarefas sejam executadas ao mesmo tempo, melhorando a eficiência das aplicações. Em Swift, podemos lidar com a concorrência usando o Grand Central Dispatch (GCD), filas de operações e a nova sintaxe async/await introduzida no Swift 5.5.
Grand Central Dispatch (GCD)
O GCD é uma API de baixo nível para gerenciar operações concorrentes em Swift. Você pode despachar tarefas para diferentes filas, tanto de forma síncrona quanto assíncrona.
Exemplo: Usando GCD
import Foundation
// Define uma função simples que simula uma tarefa demorada
func fetchData() {
print("Iniciando a busca de dados...")
sleep(2) // Simula um atraso
print("Busca de dados completa!")
}
// Despacha a função fetchData para uma fila em segundo plano
DispatchQueue.global(qos: .background).async {
fetchData()
}
// Continua executando outro código
print("Isso será impresso enquanto os dados estão sendo buscados.")
// Mantém a thread principal ativa para ver a saída
sleep(3)
Explicação:
- A função
fetchData
simula uma tarefa demorada usandosleep
. - Despachamos a função
fetchData
assincronamente para uma fila em segundo plano, permitindo que a thread principal continue em execução. - O uso de
DispatchQueue.global(qos: .background)
executa a tarefa em uma thread de fundo de baixa prioridade.
Filas de Operações
Outra maneira de lidar com a concorrência em Swift é utilizando Filas de Operações. Isso fornece uma abstração de nível mais alto em comparação ao GCD e permite um gerenciamento mais complexo das tarefas.
Exemplo: Usando Filas de Operações
import Foundation
// Define uma operação personalizada
class DataFetchOperation: Operation {
override func main() {
if isCancelled { return }
print("Iniciando a busca de dados na operação...")
sleep(2) // Simula um atraso
print("Busca de dados completa na operação!")
}
}
// Cria uma fila de operações
let operationQueue = OperationQueue()
// Cria e adiciona uma nova operação à fila
let fetchOperation = DataFetchOperation()
operationQueue.addOperation(fetchOperation)
// Continua executando outro código
print("Isso será impresso enquanto a operação está sendo executada.")
// Mantém a thread principal ativa para ver a saída
sleep(3)
Explicação:
- Criamos uma subclasse de
Operation
para encapsular nossa tarefa. - A
OperationQueue
pode gerenciar várias operações e executá-las concorrentemente. - A thread principal continua executando enquanto a operação é executada em segundo plano.
Async/Await em Swift
Com a introdução do Swift 5.5, agora temos uma maneira mais simples de lidar com código assíncrono usando async
e await
. Essa sintaxe nos permite escrever código assíncrono de uma forma mais sequencial e legível.
Exemplo: Usando Async/Await
import Foundation
// Define uma função assíncrona
func fetchData() async {
print("Iniciando a busca de dados com async/await...")
await Task.sleep(2 * 1_000_000_000) // Simula um atraso
print("Busca de dados completa com async/await!")
}
// Define a função principal
func main() async {
await fetchData()
print("Isso é impresso após os dados serem buscados.")
}
// Executa a função principal
Task {
await main()
}
// Mantém a thread principal ativa para ver a saída
sleep(3)
Explicação:
- A função
fetchData
é marcada comoasync
, permitindo que seja chamada comawait
. - O método
Task.sleep
é usado para simular um atraso sem bloquear a thread. - A função
main
orquestra a busca de dados e imprime a mensagem depois.
Conclusão
Nesta aula, exploramos três maneiras principais de lidar com a concorrência em Swift: Grand Central Dispatch (GCD), Filas de Operações e a sintaxe async/await. Cada método tem suas vantagens, e você pode escolher o melhor com base no seu caso de uso específico. A programação assíncrona melhora a capacidade de resposta das aplicações e permite um desempenho melhor, especialmente ao lidar com tarefas que dependem de I/O.