0Pricing
Swift Academy · Lección

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 })  // 14

Comprobació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 @escaping para 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.

Todas las lecciones de este curso

  1. Captura de valores por referencia
  2. Cierres escapables
  3. Listas de captura y weak self
  4. Autoclosures
← Volver a Swift Academy