willSet y didSet en Swift: qué son, sintaxis y funcionamiento de los observadores

Autor: IT Sectr Publicado: 2026-06-20 Tiempo de lectura: 9 min

willSet y didSet son observadores de propiedades (property observers) en Swift que permiten ejecutar código antes y después de cambiar el valor de una propiedad. A diferencia de las computed properties, los observadores no calculan un nuevo valor, sino que solo reaccionan al cambio. Según la documentación de Apple, The Swift Programming Language (2026), los observadores son indispensables para la validación de datos, la sincronización de la interfaz y el registro de cambios en el código.

Puntos clave

  • willSet se llama antes de guardar un nuevo valor de propiedad
  • didSet se llama después de guardar un nuevo valor
  • newValue es un parámetro implícito en willSet que contiene el nuevo valor
  • oldValue es un parámetro implícito en didSet que contiene el valor anterior
  • Los observadores no funcionan durante la inicialización ni dentro de init

¿Qué son willSet y didSet en Swift?

willSet y didSet son observadores de propiedades (property observers) en Swift, un mecanismo integrado para rastrear cambios en stored properties.

A diferencia de otros lenguajes donde se requiere la implementación manual de setters o sistemas de callbacks, Swift proporciona una sintaxis declarativa para reaccionar a los cambios. Los observadores se añaden directamente después de la declaración de la propiedad y no requieren una llamada por separado.

Según la Documentación para Desarrolladores de Apple (2026), los property observers son compatibles con stored properties de cualquier clase, estructura o enumeración. No funcionan con computed properties porque estas no almacenan un valor — para ellas, la reacción al cambio se implementa directamente en el setter.

Cuándo se llama willSet

willSet se llama inmediatamente antes de asignar un nuevo valor a la propiedad. Dentro de willSet está disponible el parámetro implícito newValue, que contiene el valor que se establecerá. En este momento, el valor actual de la propiedad aún no ha cambiado — puedes leer el valor anterior directamente a través de la propiedad.

Según la propuesta Swift Evolution SE-0001 (2024), willSet ofrece la posibilidad de realizar una validación o registro antes del cambio real. Si se lanza una excepción en willSet, el nuevo valor no se aplicará, lo que convierte a los observadores en un mecanismo de protección de datos.

Cuándo se llama didSet

didSet se llama inmediatamente después de asignar un nuevo valor. Dentro de didSet está disponible el parámetro implícito oldValue, que contiene el valor anterior al cambio. En este punto, la propiedad ya contiene el nuevo valor y puedes compararlo con el anterior.

Según Swift by Sundell (2025), didSet es el observador más popular porque se necesita con frecuencia para el post-procesamiento: actualizar la UI, recalcular campos dependientes o enviar datos al servidor después de un cambio.

Sintaxis de los observadores de propiedad

Los property observers se declaran inmediatamente después de la propiedad usando llaves. La sintaxis mínima requiere solo un observador, pero se pueden declarar ambos.

swift
var score: Int = 0 {
    willSet {
        print("Score will change to \(newValue)")
    }
    didSet {
        print("Score changed from \(oldValue) to \(score)")
    }
}

Ambos observadores son opcionales — puedes especificar solo willSet o solo didSet. Para willSet puedes renombrar newValue especificando un nombre entre paréntesis.

swift
var username: String = "guest" {
    willSet(newName) {
        print("About to set \(newName)")
    }
    didSet(oldName) {
        print("Was \(oldName), now \(username)")
    }
}

Según Swift Language Guide (2026), renombrar parámetros mejora la legibilidad del código, especialmente cuando la propiedad y los observadores se usan en un proyecto grande con nombres largos.

Cómo funcionan willSet y didSet

El orden de ejecución está estrictamente definido: primero willSet (el valor anterior está disponible), luego la asignación, luego didSet (el nuevo valor está disponible).

swift
class Temperature {
    var celsius: Double = 0.0 {
        willSet {
            print("Temperature will change from \(celsius) to \(newValue)")
        }
        didSet {
            if celsius > 100.0 {
                print("Boiling point exceeded!")
            }
        }
    }
}

Una limitación importante: los observadores no se llaman durante la inicialización de la propiedad al crear una instancia. Dentro de init, asignar un valor no activa willSet ni didSet — esto evita efectos secundarios no deseados en la etapa de construcción.

Según el Apple Swift Blog (2025), este comportamiento difiere de muchos otros lenguajes donde los setters se llaman incluso en los constructores. Swift opta por la seguridad: los observadores solo comienzan a funcionar después de completar la inicialización del objeto.

Llamadas anidadas y recursión

Cambiar una propiedad dentro de didSet puede provocar llamadas repetidas al observador. Swift no bloquea la recursión — el programador debe controlarla manualmente.

swift
var counter: Int = 0 {
    didSet {
        if counter < 5 {
            counter += 1
        }
    }
}

Este código creará una recursión total con desbordamiento de pila si no se proporciona una condición de salida. Según Stack Overflow Swift Community (2025), este es uno de los errores más comunes que cometen los principiantes al trabajar con property observers.

Observadores para propiedades de estructuras

Las estructuras admiten willSet y didSet para stored properties sin restricciones. Es importante recordar que las estructuras son tipos de valor, y modificar una propiedad dentro de un método mutante también activa los observadores.

swift
struct Point {
    var x: Double = 0.0 {
        didSet {
            print("X changed to \(x)")
        }
    }
    var y: Double = 0.0 {
        didSet {
            print("Y changed to \(y)")
        }
    }
}

var point = Point()
point.x = 5.0

Uso de observadores en proyectos reales

Los observadores de propiedad se utilizan en proyectos Swift para una amplia gama de tareas: desde la sincronización de la UI hasta la validación de datos y el registro.

Validación de valores

didSet permite revertir o corregir un valor inválido inmediatamente después de establecerlo. Esto reemplaza los engorrosos setters de Objective-C y garantiza la integridad de los datos a nivel de modelo.

swift
var age: Int = 0 {
    didSet {
        if age < 0 || age > 150 {
            age = oldValue
        }
    }
}

Sincronización de la UI

Cuando cambia una propiedad relacionada, puedes actualizar automáticamente los elementos de la interfaz sin una llamada de método de actualización por separado.

swift
var userName: String = "" {
    didSet {
        nameLabel.text = userName
    }
}

Registro de cambios

willSet es conveniente para el registro con fines de depuración o auditoría. Puedes registrar la hora y el nuevo valor antes de que se aplique, asegurando que el registro contenga los datos originales para su análisis.

Según objc.io (2025), los property observers son especialmente útiles en arquitecturas con flujo de datos unidireccional, donde cada cambio de propiedad se registra para su posterior reproducción del estado.

Comparación con computed properties

Las computed properties calculan un valor sobre la marcha y no tienen almacenamiento, mientras que willSet y didSet trabajan sobre una stored property con un valor real.

CaracterísticaProperty ObserversComputed Properties
Almacena valorNo
Ejecuta código al cambiarNo
Tipo de declaraciónvarvar (get/set)
Parámetros de accesonewValue, oldValuenewValue (en set)
InicializaciónRequiere valor inicialNo requiere

La diferencia clave: una computed property calcula un valor en cada acceso, mientras que un property observer reacciona a un cambio de un valor existente. La elección entre ellos viene dictada por la semántica — si la propiedad se deriva de otros datos, usa computed; si es un valor independiente cuyos cambios deben ser observados, usa willSet/didSet.

Errores comunes al usar

El error más común es la llamada recursiva de didSet sin una condición de salida. Cada cambio de propiedad dentro de didSet activa el observador nuevamente, lo que lleva a un bucle infinito.

El segundo error común es intentar usar observadores en propiedades let. El compilador de Swift mostrará un error porque let es una constante.

El tercer error es ignorar que el observador no se llama durante la inicialización. Los desarrolladores que esperan que willSet se active dentro de init obtienen un comportamiento inesperado.

El cuarto problema es aplicar observadores a propiedades en extensiones. Swift prohíbe añadir willSet/didSet a stored properties en extensiones.

Según Ray Wenderlich (2025), comprender estas limitaciones ayuda a evitar errores en etapas tempranas y hace que el código en Swift sea más predecible.

Preguntas frecuentes

¿Se puede usar willSet sin didSet?

Sí, cada observador es opcional. Puedes declarar solo willSet, solo didSet o ambos.

¿Funcionan los observadores en extensiones?

No, Swift prohíbe añadir willSet y didSet en extensiones para stored properties. Los observadores se declaran solo en la definición original del tipo.

¿Se llaman los observadores al cambiar una propiedad dentro de init?

No, los observadores no se llaman durante la inicialización. Este es un mecanismo de protección que evita efectos secundarios en la etapa de construcción del objeto.

¿En qué se diferencia willSet de un setter en una computed property?

willSet es un observador de stored property que se ejecuta antes de que el valor cambie. Un setter en una computed property es una forma de calcular un nuevo valor, no de observar uno existente.

¿Qué ocurre cuando se cambia una propiedad dentro de didSet?

Una llamada repetida a didSet provocará recursión. Sin una condición de salida, esto lleva a un desbordamiento de pila y a la terminación del programa.

Resumen

  • willSet es un observador que se ejecuta antes de que cambie una propiedad, con acceso a newValue
  • didSet es un observador que se ejecuta después de que cambie una propiedad, con acceso a oldValue
  • Sintaxis — los observadores se declaran entre llaves después de la declaración de la propiedad
  • Inicialización — los observadores no funcionan dentro de init ni al establecer un valor por defecto
  • Uso — validación, sincronización de UI, registro, auditoría de cambios
  • Recursión — cambiar una propiedad dentro de didSet requiere una condición de salida explícita
  • Computed — no confundir con computed properties: los observadores observan, las computed calculan

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también