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 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.
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.
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.
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.
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.
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.
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).
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.
Cambiar una propiedad dentro de didSet puede provocar llamadas repetidas al observador. Swift no bloquea la recursión — el programador debe controlarla manualmente.
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.
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.
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
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.
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.
var age: Int = 0 {
didSet {
if age < 0 || age > 150 {
age = oldValue
}
}
}
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.
var userName: String = "" {
didSet {
nameLabel.text = userName
}
}
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.
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ística | Property Observers | Computed Properties |
|---|---|---|
| Almacena valor | Sí | No |
| Ejecuta código al cambiar | Sí | No |
| Tipo de declaración | var | var (get/set) |
| Parámetros de acceso | newValue, oldValue | newValue (en set) |
| Inicialización | Requiere valor inicial | No 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.
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
Sí, cada observador es opcional. Puedes declarar solo willSet, solo didSet o ambos.
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.
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.
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.
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
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.
Lea también