Swift Concurrency introduz structured concurrency com verificacao em compile-time. O compilador garante que dados compartilhados sao acessados de forma segura, eliminando data races em tempo de compilacao.

GCD vs Structured Concurrency

Swift Concurrency substitui Grand Central Dispatch (GCD) com um modelo que o compilador pode verificar. Tasks formam uma arvore hierarquica β€” se uma task pai e cancelada, todas as filhas sao canceladas automaticamente.

AspectoGCD (DispatchQueue)Structured Concurrency
ModeloClosures em filasasync/await com Tasks
CancelamentoManual (flag booleana)Automatico e hierarquico
Erro handlingCallbacks com Resulttry/catch nativo
Thread safetyResponsabilidade do devCompilador verifica via Sendable
PrioridadeQoS classesTaskPriority (herda do pai)
DepuracaoStack frames fragmentadosStack traces completos

AsyncStream

AsyncStream permite criar sequencias assincronas que emitem valores ao longo do tempo. Ideal para adaptar APIs callback-based para o mundo async/await.

// AsyncStream β€” adaptar delegate para async func frameStream() -> AsyncStream<ProcessedFrame> { AsyncStream { continuation in let handler = FrameHandler { frame in continuation.yield(frame) } continuation.onTermination = { _ in handler.stop() } handler.start() } } // Consumir com for-await func processFrames() async { for await frame in frameStream() { guard !Task.isCancelled else { break } await analyzeFrame(frame) } }

CheckedContinuation

CheckedContinuation faz a ponte entre codigo callback-based e async/await. O "checked" significa que o runtime verifica se resume e chamado exatamente uma vez.

// CheckedContinuation β€” ponte callback -> async func requestCameraPermission() async -> Bool { await withCheckedContinuation { continuation in AVCaptureDevice.requestAccess(for: .video) { granted in continuation.resume(returning: granted) // Chamar resume 2x causa crash (checked!) } } } // Throwing version func loadImage(at url: URL) async throws -> UIImage { try await withCheckedThrowingContinuation { continuation in ImageLoader.load(url: url) { result in switch result { case .success(let image): continuation.resume(returning: image) case .failure(let error): continuation.resume(throwing: error) } } } }