Historia del tema:
Defer fue añadido en Swift (inspirado en sus análogos en Go, C#) para garantizar la limpieza de recursos incluso cuando ocurren errores, se sale de la función o se retornan valores desde diferentes puntos de las funciones.
Problema:
Liberación prematura, limpieza de recursos olvidada (por ejemplo, cerrando archivos, registrando, rollback de transacciones). A veces se confunde el orden de ejecución, erróneamente asumiendo que defer se ejecuta en el momento de su declaración.
Solución:
Defer es un bloque especial que pospone la ejecución del código hasta el final del ámbito actual (scope), generalmente de la función. Todos los defer se ejecutan en orden inverso de su colocación (LIFO). Esto permite gestionar de manera centralizada la limpieza de recursos, liberación de memoria o rollback de transacciones.
Ejemplo de código:
func processFile() { let file = File("/tmp/data.txt") file.open() defer { file.close() print("Archivo cerrado") } // Trabajando con el archivo print("Leyendo datos…") }
Características clave:
¿Se ejecuta el código dentro de defer si la aplicación falla (crash) antes de salir de la función?
No, el código defer solo se ejecuta al salir correctamente del ámbito (scope). Si la aplicación se cierra de forma inesperada (por ejemplo, error fatal), defer no se ejecutará.
¿Se puede usar return dentro de defer?
No, no se puede. El bloque defer no permite retornar valores ni finalizar el ámbito, solo instrucciones.
¿Puede defer ser usado para modificar variables declaradas antes de defer?
Sí, defer captura los valores del stack actual en el momento de su ejecución. Se pueden modificar los valores declarados antes de defer, y se conservarán al salir del scope.
Ejemplo de código:
func example() -> Int { var result = 0 defer { result = 42 } return result // defer se ejecutará, el resultado será 42 }
El archivo se abre, pero solo se cierra explícitamente al final de la función, y en caso de errores o salida anticipada de la función, el archivo permanece abierto.
Ventajas:
Desventajas:
Uso de defer para cerrar el archivo inmediatamente después de abrirlo. Incluso si ocurre una excepción o retorno de la función, el archivo se cerrará de forma garantizada.
Ventajas:
Desventajas: