Observer delle proprietà
Fa parte della sezione Programmazione orientata agli oggetti del percorso Swift di Coddy. Lezione 13 di 57.
Un osservatore di proprietà esegue il codice ogni volta che una proprietà memorizzata cambia. didSet viene eseguito subito dopo che il nuovo valore è stato memorizzato e al suo interno oldValue contiene il valore precedente:
class Player {
var score = 0 {
didSet {
print("score \(oldValue) -> \(score)")
}
}
}
let p = Player()
p.score = 10
p.score += 5Output:
score 0 -> 10
score 10 -> 15willSet viene eseguito prima della modifica, con il valore in arrivo come newValue. Gli osservatori non vengono eseguiti quando la proprietà riceve il suo valore iniziale:
struct Thermostat {
var target = 20 {
willSet { print("changing to \(newValue)") }
didSet { print("changed from \(oldValue)") }
}
}
var t = Thermostat()
t.target = 22Output:
changing to 22
changed from 20didSet è un buon posto per mantenere valido un valore. Assegnare un valore alla proprietà all'interno del proprio didSet non attiva di nuovo l'osservatore:
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)Output:
10
0Gli osservatori possono anche mantenere uno storico o aggiornare lo stato correlato, mantenendo così questa logica accanto alla proprietà invece di disperderla nel codice:
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)Output:
[100, -30]Sfida
FacileCompleta la classe Tank. La sua proprietà memorizzata level deve rimanere tra 0 e capacity: aggiungi un didSet che corregga i valori al di fuori di tale intervallo e aggiunga l'avviso low a alerts ogni volta che il livello corretto scende sotto il 20% della capacità (e il livello precedente non era basso).
Il codice fornito legge la capacità e poi applica modifiche +n o -n. Stampa il livello dopo ogni modifica e infine alerts: seguito dal numero di avvisi.
Il tuo codice va inserito in Tank.swift. main.swift contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
// Codice di input/output fornito: lascialo così com'è
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)")
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiMetodi e selfInizializzatoriLe classi sono riferimentiRiepilogo - Tessera della biblioteca4Incapsulamento
Controllo degli accessiSola lettura dall’esternoProteggere lo statoInizializzatori che possono fallireRiepilogo - Conto bancario7Polimorfismo e tipi generici
PolimorfismoCasting dei tipiFunzioni genericheTipi genericiRipasso - Calcolatore di forme2Struct e tipi valore
Le structSemantica dei valoriMetodi mutantiStruct o classeRiepilogo - Articolo di inventario5Ereditarietà
SottoclassiSovrascrivere i metodiInizializzatori e superfinal e gerarchieRiepilogo - Gerarchia dei dipendenti8Protocolli standard
CustomStringConvertibleEquatableComparableHashableRiepilogo - Ordinamento personalizzato11Progetto: Gestione della biblioteca
Libri e utentiPrestito dei libri3Le proprietà in dettaglio
Proprietà calcolateObserver delle proprietàMembri staticiEnum con metodiRiepilogo - Registro delle temperatureEsercitati da solo: Playground Swift