ProgramaciónProgramador Swift

¿Qué es 'defer' en Swift? ¿Cómo funciona y para qué se utiliza, qué escenarios no estándar existen para su uso?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

El operador defer retrasa la ejecución del código hasta que se sale del ámbito actual, generalmente de una función. Es útil para la limpieza de recursos, cierre de archivos y liberación de memoria — lo que se conoce como limpieza automatizada.

Características:

  • Los bloques defer se ejecutan en el orden inverso a su declaración (LIFO).
  • La llamada ocurre siempre — tanto en la salida normal de la función como al lanzar un error.
  • Permite evitar la duplicación del código de limpieza y mantiene una arquitectura limpia de las funciones.

Ejemplo:

func processFile() { let file = openFile() defer { closeFile(file) } // Trabajo con el archivo // el archivo se cerrará incluso en caso de throw o return }

Uso atípico: imitación parcial de construcciones tipo 'finally', agrupación de código para registro y seguimiento de tiempos de ejecución.

Pregunta capciosa.

¿Se ejecutará defer si la aplicación termina durante la ejecución de la función?

— No. Defer se ejecuta solo en la salida normal del ámbito (return, throw o salida normal). Si la aplicación termina abruptamente (por ejemplo, debido a una señal SIGKILL o fatalError), los bloques defer no tendrán tiempo de ejecutarse.

Ejemplo:

func foo() { defer { print("Limpiar") } fatalError("¡Error!") // defer no se ejecutará }

Ejemplos de errores reales debido al desconocimiento de los matices del tema.


Historia

Una función que trabajaba con sockets no limpiaba la conexión en caso de throw. Los datos permanecían colgados, las conexiones no se liberaban. Después de introducir defer, todo funcionó correctamente: los recursos se cerraban siempre.


Historia

Un desarrollador intentó confiar en defer para liberar un estado global. Cuando ocurrió un fatalError, el recurso no se liberó, lo que provocó bloqueos en los servicios y la necesidad de reinicio.


Historia

En la función se declararon varios defer, pensando que se ejecutarían en el orden de declaración. Como resultado, los recursos se cerraban en un orden incorrecto (por ejemplo, primero se cerró el descriptor de archivo, y luego se intentó acceder a él). Solución: recordar el orden LIFO de ejecución de los bloques defer.