Closures Escapáveis
Armazene closures que sobrevivem à função que as criou.
Closures Escapáveis é uma aula grátis de Swift Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Swift Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Swift Academy inclui 4 aulas no total.
Escapante versus não escapante
Por padrão, um parâmetro de fechamento é não escapante: ele deve ser chamado antes que a função retorne. Marque-o como @escaping se ele puder ser armazenado e chamado posteriormente.
Um fechamento não escapante
Este fechamento é executado de forma síncrona e desaparece quando a função retorna:
func run(_ work: () -> Void) {
work()
}
run { print("done now") } // "done now"Por que @escaping é necessário
Armazenar um fechamento para uso posterior exige @escaping:
var handlers: [() -> Void] = []
func register(_ handler: @escaping () -> Void) {
handlers.append(handler) // escapes the function
}
register { print("later") }
handlers[0]() // "later"Escape com trabalho assíncrono
handlers de conclusão escapam porque são executados depois que a função retorna:
func load(then completion: @escaping (String) -> Void) {
// imagine async work
completion("data")
}
load { result in print(result) } // "data"self deve ser explícito
Dentro de um fechamento escapante, você deve escrever self. explicitamente ao acessar membros da instância — um lembrete de que o fechamento pode manter self.
self explícito em um fechamento escapante
O compilador exige a referência explícita:
class Loader {
var name = "L"
func start(_ done: @escaping () -> Void) {
let cb = { print(self.name); done() }
cb()
}
}
Loader().start { print("finished") } // "L" then "finished"Armazenando vários retornos de chamada
Closures escapantes permitem criar listas de observadores:
class Emitter {
private var listeners: [(Int) -> Void] = []
func on(_ l: @escaping (Int) -> Void) { listeners.append(l) }
func fire(_ v: Int) { listeners.forEach { $0(v) } }
}
let e = Emitter()
e.on { print("got \($0)") }
e.fire(7) // "got 7"Retornando um fechamento armazenado
Closures mantidos em propriedades são escapantes:
class Button {
var action: (() -> Void)?
func setAction(_ a: @escaping () -> Void) { action = a }
}
let b = Button()
b.setAction { print("tapped") }
b.action?() // "tapped"Closures opcionais escapam
Um parâmetro de fechamento opcional é implicitamente escapante (ele é envolvido em Optional), portanto pode ser armazenado:
func maybe(_ f: (() -> Void)?) {
f?()
}
maybe { print("ran") } // "ran"Escapando para um vetor de tarefas
Uma fila de trabalho adiado é um caso clássico de uso de escape — cada fechamento é armazenado e depois executado:
var tasks: [() -> Int] = []
func schedule(_ task: @escaping () -> Int) {
tasks.append(task)
}
schedule { 1 + 1 }
schedule { 10 * 2 }
print(tasks.map { $0() }) // [2, 20]Observação sobre desempenho
Fechamentos não escapantes podem ser otimizados de forma mais agressiva (não precisam de alocação no heap). Mantenha os fechamentos não escapantes quando puder; faça-os escapantes somente quando realmente os armazenar ou adiar.
func sum(_ xs: [Int], _ f: (Int) -> Int) -> Int {
xs.reduce(0) { $0 + f($1) } // non-escaping, fast
}
print(sum([1, 2, 3]) { $0 * $0 }) // 14Verificação rápida
Quando um parâmetro de fechamento precisa ser marcado com @escaping?
Recapitulação
Você aprendeu sobre closures escapantes:
- Não escapante é o padrão; os closures são executados antes que a função retorne
@escapingé necessário para armazenar ou adiar um fechamento- Closures escapantes exigem acesso explícito a
self. - Parâmetros de fechamento opcionais escapam implicitamente; prefira os não escapantes para obter mais velocidade
Próximo: listas de captura e self fraco.
Perguntas Frequentes
A aula “Closures Escapáveis” é grátis?
Sim — o texto completo de “Closures Escapáveis” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Swift Academy, atualize para CoddyKit PRO. O curso de Swift Academy inclui 4 aulas no total.
O que vou aprender em “Closures Escapáveis”?
Armazene closures que sobrevivem à função que as criou. Você pratica Swift Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Swift Academy?
Nenhuma experiência prévia é necessária. Swift Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Closures Escapáveis”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Swift Academy?
Sim. Cada aula de Swift Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Captura de Valores por Referência
- Closures Escapáveis
- Listas de Captura e Weak Self
- Autoclosures