Obserwatory właściwości
Część sekcji Programowanie obiektowe ścieżki Swift w Coddy. Lekcja 13 z 57.
Obserwator właściwości uruchamia kod za każdym razem, gdy zmienia się przechowywana właściwość. didSet uruchamia się zaraz po zapisaniu nowej wartości, a wewnątrz niego oldValue przechowuje poprzednią wartość:
class Player {
var score = 0 {
didSet {
print("score \(oldValue) -> \(score)")
}
}
}
let p = Player()
p.score = 10
p.score += 5Wynik:
score 0 -> 10
score 10 -> 15willSet działa przed zmianą, a nowa wartość jest dostępna jako newValue. Obserwatory nie są uruchamiane, gdy właściwość otrzymuje wartość początkową:
struct Thermostat {
var target = 20 {
willSet { print("changing to \(newValue)") }
didSet { print("changed from \(oldValue)") }
}
}
var t = Thermostat()
t.target = 22Wynik:
changing to 22
changed from 20didSet to dobre miejsce, by utrzymywać wartość w prawidłowym zakresie. Przypisanie wartości właściwości wewnątrz jej własnego didSet nie wywołuje obserwatora ponownie:
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)Wynik:
10
0Obserwatory mogą również przechowywać historię lub aktualizować powiązany stan, dzięki czemu ta logika znajduje się obok właściwości, zamiast być rozproszona w kodzie:
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)Wynik:
[100, -30]Wyzwanie
ŁatwyUzupełnij klasę Tank. Jej przechowywana właściwość level musi mieścić się w zakresie od 0 do capacity: dodaj didSet, który koryguje wartości spoza tego zakresu i dopisuje ostrzeżenie low do alerts, gdy skorygowany poziom spadnie poniżej 20% pojemności (a poprzedni poziom nie był niski).
Dostarczony kod odczytuje pojemność, a następnie zmienia poziom o +n lub -n. Po każdej zmianie wyświetla poziom, a na końcu alerts: wraz z liczbą ostrzeżeń.
Umieść swój kod w pliku Tank.swift. Plik main.swift zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
// Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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)")
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Klasy i obiekty
Praca z plikamiDefiniowanie klasMetody i selfInicjalizatoryKlasy są referencjamiPowtórzenie — karta biblioteczna4Hermetyzacja
Kontrola dostępuTylko do odczytu z zewnątrzOchrona stanuInicjalizatory, które mogą zawieśćPodsumowanie — konto bankowe7Polimorfizm i typy generyczne
PolimorfizmRzutowanie typówFunkcje generyczneTypy generycznePodsumowanie – kalkulator kształtów2Struktury i typy wartościowe
StrukturySemantyka wartościMetody modyfikująceStruktura czy klasaPodsumowanie – element inwentarza5Dziedziczenie
PodklasyPrzesłanianie metodInicjalizatory i superfinal i hierarchiePodsumowanie — hierarchia pracowników8Standardowe protokoły
CustomStringConvertibleEquatableComparableHashablePodsumowanie — własne sortowanie11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książek3Właściwości w szczegółach
Właściwości obliczaneObserwatory właściwościElementy statyczneTypy wyliczeniowe z metodamiPodsumowanie – rejestr temperaturyPoćwicz samodzielnie: Edytor online Swift