Swiftのクラスで設定するプロパティにはプロパティオブザーバーという機能がある。

これはプロパティの値に更新があった時に発火するイベント処理で、値が更新される直前に呼び出されるwillSet、値が更新された直後に呼び出されるdidSetと、二つの機能を使うことができる。

まずは基本的なコードを見ていこう。

class Player {
    var times = 0
    var level:Int {
        willSet {
            print("-----------")
            print("willSet \(newValue)")
        }
        didSet {
            if oldValue != level {
                times += 1
                print("\(times)回目の更新")
                print("\(oldValue) -> \(level)")
            } else {
                print("変化なし")
            }
        }
    }
    
    init() {
        level = 0
    }
}

上記のPlayerクラスでは、値の更新回数を保持するtimes(Storedプロパティ)と、プレイヤーのレベルを表すlevel(Computedプロパティ)、二つのプロパティを持っている。

willSet内では新しく設定された値に対しnewValueでアクセスでき、didSetでは更新される前の値にoldValueでアクセスできる。

それではこのPlayerクラスをインスタンス化し、プロパティの値の変化を可視化してみよう。

let thePlayer = Player()
thePlayer.level = 10
thePlayer.level = 10
thePlayer.level = 15

// 以下実行結果
-----------
willSet 10
1回目の更新
0 -> 10
-----------
willSet 10
変化なし
-----------
willSet 15
2回目の更新
10 -> 15

結果を見てのとおり、levelの更新に合わせてwillSet、didSetの処理が実行されていることが分かる。