Menu
Coddy logo textTech

Observadores de propiedades

Parte de la sección Programación orientada a objetos del Journey de Swift de Coddy. Lección 13 de 57.

Un observador de propiedades ejecuta código cada vez que cambia una propiedad almacenada. didSet se ejecuta justo después de almacenar el nuevo valor, y dentro de él oldValue contiene el valor anterior:

class Player {
    var score = 0 {
        didSet {
            print("score \(oldValue) -> \(score)")
        }
    }
}

let p = Player()
p.score = 10
p.score += 5

Salida:

score 0 -> 10
score 10 -> 15

willSet se ejecuta antes del cambio, con el valor entrante como newValue. Los observadores no se ejecutan cuando la propiedad recibe su valor inicial:

struct Thermostat {
    var target = 20 {
        willSet { print("changing to \(newValue)") }
        didSet { print("changed from \(oldValue)") }
    }
}

var t = Thermostat()
t.target = 22

Salida:

changing to 22
changed from 20

didSet es un buen lugar para mantener válido un valor. Asignar a la propiedad dentro de su propio didSet no vuelve a activar el observador:

struct Volume {
    var level = 5 {
        didSet {
            if level > 10 { level = 10 }
            if level < 0 { level = 0 }
        }
    }
}

var v = Volume()
v.level = 42
print(v.level)
v.level = -3
print(v.level)

Salida:

10
0

Los observadores también pueden mantener un historial o actualizar un estado relacionado, lo que mantiene esa lógica junto a la propiedad en lugar de dispersarla por el código:

class Account {
    var history: [Int] = []
    var balance = 0 {
        didSet { history.append(balance - oldValue) }
    }
}

let a = Account()
a.balance = 100
a.balance = 70
print(a.history)

Salida:

[100, -30]
challenge icon

Desafío

Fácil

Completa la clase Tank. Su propiedad almacenada level debe mantenerse entre 0 y capacity: añade un didSet que corrija los valores fuera de ese rango y que añada una advertencia low a alerts siempre que el nivel corregido termine por debajo del 20 % de la capacidad (y el nivel anterior no fuera bajo).

El código proporcionado lee la capacidad y después cambia +n o -n. Imprime el nivel después de cada cambio y finalmente alerts: con el número de advertencias.

Tu código va en Tank.swift. main.swift contiene el código de entrada/salida proporcionado y no se puede editar.

Pruébalo tú mismo

// Código de entrada/salida suministrado: déjalo tal como está
var input: [String] = []
while let line = readLine() { input.append(line) }
let tank = Tank(capacity: Int(input[0])!)
for cmd in input.dropFirst() {
    let n = Int(cmd.dropFirst())!
    tank.level += cmd.hasPrefix("+") ? n : -n
    print(tank.level)
}
print("alerts: \(tank.alerts.count)")
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación orientada a objetos

Practica por tu cuenta: Playground de Swift