Una instantánea en la lista de captura no es una copia profunda del objeto. Un entero conserva su valor al crear la clausura; una referencia de clase apunta al mismo objeto. weak es otra decisión de propiedad y no mantiene vivo el destino.
Mecanismo y decisión de diseño
Una clausura que captura una variable local mutable puede observar cambios posteriores. Una lista como [number] conserva el valor inicial. Guardar un parámetro de clausura para usarlo tras retornar requiere @escaping, pero no implica asincronía ni fuga de memoria. Fuente primaria
Código reproducible
En una función creamos capturas viva y de instantánea, y cambiamos number a 2. Capturamos una referencia antes de cambiar el objeto a 3 y liberamos otro objeto capturado con weak. Queue guarda el callback, lo ejecuta una vez y lo borra.
Este ejemplo independiente se ejecutó el 2026-10-23 con Apple Swift 6.4 para arm64 macOS, en modo de lenguaje Swift 6. No necesita red ni paquetes adicionales.
Descargar el archivo Swift completo
Ejecuta el comando en la carpeta de descarga. Las precondiciones detienen la ejecución si falla una comprobación. No uses -Ounchecked: elimina estas comprobaciones.
swift -swift-version 6 swift-closure-capture-weak-self-escaping.swift
final class Box { var value = 1 }
final class Queue {
private var action: (() -> Int)?
func enqueue(_ action: @escaping () -> Int) { self.action = action }
func run() -> Int? {
let current = action
action = nil
return current?()
}
}
func experiment() {
var number = 1
let live = { number }
let snapshot = { [number] in number }
number = 2
precondition(live() == 2 && snapshot() == 1)
let box = Box()
let capturedReference = { [box] in box.value }
box.value = 3
precondition(capturedReference() == 3)
var temporary: Box? = Box()
let weakRead = { [weak box = temporary] in box?.value }
precondition(weakRead() == 1)
temporary = nil
precondition(weakRead() == nil)
let queue = Queue()
queue.enqueue(snapshot)
precondition(queue.run() == 1 && queue.run() == nil)
print("variable=2 snapshot=1 captured-object=3 weak-after-release=nil queued=1 then=nil")
}
experiment()
Salida registrada e interpretación
variable=2 snapshot=1 captured-object=3 weak-after-release=nil queued=1 then=nil
La captura viva devuelve 2; la instantánea numérica, 1; y la referencia capturada observa 3. weak devuelve nil tras liberar el objeto. Queue devuelve 1 y luego nil. Esta Queue ilustra almacenamiento síncrono, no es un planificador asíncrono.
Alcance y limitaciones
Capturar no implica necesariamente asignar memoria en el heap; el compilador puede optimizarla. [weak self] no es obligatorio: decide si omitir el trabajo al desaparecer el propietario es válido. Investiga rutas de propiedad directas e indirectas para confirmar un ciclo.
Qué comprobar después
Documenta quién posee los callbacks guardados, cuándo se borran y qué significa cancelarlos. No debilites referencias automáticamente si la operación necesita mantener vivo al propietario. El experimento ARC demuestra cómo romper un ciclo real.
Fuentes y verificación
- The Swift Programming Language: ClosuresSwift.org · Documentación oficial · Consultado 23 de octubre de 2026Respalda: Fuente del contrato de implementación y de la explicación. La salida se comprobó por separado con el experimento incluido aquí.

