Los closures en Swift son bloques de código independientes que pueden capturar y mantener referencias a variables y constantes del contexto circundante. Permiten organizar callbacks, procesamiento asíncrono y almacenar la ejecución del código como valores de variables.
var contador = 0 let incrementador: () -> Void = { contador += 1 } incrementador() print(contador) // 1
[weak self], [unowned self]).self dentro del closure.¿Cuál es la diferencia entre strong-capture y el uso de
[weak self]o[unowned self]en la lista de captura de un closure? ¿Qué implica esto?
Respuesta:
Si no especificas [weak self] o [unowned self], el closure capturará self por referencia fuerte por defecto, lo que llevará a un retain cycle si el closure y self se refieren entre sí. [weak self] captura self por referencia débil (opcional), [unowned self] — por referencia no controlada (no opcional). Una elección incorrecta o la ausencia de una lista de captura conduce a fugas de memoria o fallos.
class Test { var closure: (() -> Void)? func setup() { closure = { [weak self] in self?.doWork() } } func doWork() { ... } }
Historia
Un programador no utilizó la lista de captura en un closure dentro de UIViewController, que iniciaba una carga de datos asíncrona. Como resultado, el controller y su vista no se liberaron, lo que llevó a una fuga de memoria después de cerrar (dismiss). El análisis de la infraestructura mostró cientos de controllers "atrapados" en la memoria.
Historia
El closure capturó self con [unowned self], pero el ciclo de vida de self terminó antes que el closure. Esto causó un fallo al intentar acceder a un objeto ya liberado — la aplicación se cerró al intentar trabajar con self dentro del closure.
Historia
En el proyecto, dentro de un closure anidado, se capturaron dos variables: una por referencia fuerte, la otra por débil. Resultó que la referencia débil se anulaba demasiado pronto, y los datos necesarios para el funcionamiento del closure se perdieron — el error se manifestó solo en una prueba de estrés bajo carga en un entorno multihilo.