Cierres escapables
Almacene cierres que sobrevivan a su función.
Cierres escapables es una lección gratuita de Swift Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Swift Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Swift Academy incluye 4 lecciones en total.
Escapables frente a no escapables
De forma predeterminada, un parámetro de closure es no escapable: debe llamarse antes de que la función devuelva el control. Márquelo con @escaping si puede almacenarse y llamarse más adelante.
Una closure no escapable
Esta closure se ejecuta de forma síncrona y deja de existir cuando la función devuelve el control:
func run(_ work: () -> Void) {
work()
}
run { print("done now") } // "done now"Por qué se necesita @escaping
Almacenar una closure para usarla más adelante requiere @escaping:
var handlers: [() -> Void] = []
func register(_ handler: @escaping () -> Void) {
handlers.append(handler) // escapes the function
}
register { print("later") }
handlers[0]() // "later"Escapable con trabajo asíncrono
Los completion handlers son escapables porque se ejecutan después de que la función devuelve el control:
func load(then completion: @escaping (String) -> Void) {
// imagine async work
completion("data")
}
load { result in print(result) } // "data"self debe ser explícito
Dentro de una closure escapable, debe escribir self. explícitamente al acceder a miembros de la instancia — es un recordatorio de que la closure puede retener self.
self explícito en una closure escapable
El compilador requiere la referencia 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"Almacenar muchos callbacks
Las closures escapables permiten crear 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"Devolver una closure almacenada
Las closures almacenadas en propiedades son escapables:
class Button {
var action: (() -> Void)?
func setAction(_ a: @escaping () -> Void) { action = a }
}
let b = Button()
b.setAction { print("tapped") }
b.action?() // "tapped"Las closures opcionales son escapables
Un parámetro de closure opcional es escapable implícitamente (está envuelto en Optional), por lo que puede almacenarse:
func maybe(_ f: (() -> Void)?) {
f?()
}
maybe { print("ran") } // "ran"Escapable en un array de tareas
Una cola de trabajo aplazado es un caso de uso clásico de las closures escapables — cada closure se almacena y luego se ejecuta:
var tasks: [() -> Int] = []
func schedule(_ task: @escaping () -> Int) {
tasks.append(task)
}
schedule { 1 + 1 }
schedule { 10 * 2 }
print(tasks.map { $0() }) // [2, 20]Nota de rendimiento
Las closures no escapables pueden optimizarse de forma más agresiva (no necesitan asignación en el heap). Mantenga las closures como no escapables cuando pueda; hágalas escapables solo cuando realmente las almacene o aplace su ejecución.
func sum(_ xs: [Int], _ f: (Int) -> Int) -> Int {
xs.reduce(0) { $0 + f($1) } // non-escaping, fast
}
print(sum([1, 2, 3]) { $0 * $0 }) // 14Comprobación rápida
¿Cuándo debe marcarse un parámetro de closure con @escaping?
Repaso
Ha aprendido sobre las closures escapables:
- Las no escapables son la opción predeterminada; las closures se ejecutan antes de que la función devuelva el control
- Se necesita
@escapingpara almacenar o aplazar una closure - Las closures escapables requieren acceder explícitamente a
self. - Los parámetros de closure opcionales son escapables implícitamente; prefiera las no escapables para obtener mayor velocidad
Siguiente: listas de captura y weak self.
Preguntas frecuentes
¿La lección «Cierres escapables» es gratis?
Sí — el texto completo de «Cierres escapables» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Swift Academy, actualiza a CoddyKit PRO. El curso de Swift Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Cierres escapables»?
Almacene cierres que sobrevivan a su función. Practicas Swift Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Swift Academy?
No se requiere experiencia previa. Swift Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Cierres escapables»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Swift Academy?
Sí. Cada lección de Swift Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.