#KVOって何?
KVOというものは簡単に言うと、プロパティーの値の変化を通知してくれる仕組みのことです。
#使い方
初めは難しいかもしれないですが、実際に使ってみると簡単です。
まずはコードから
kvo.swift
import Foundation
class Person: NSObject {
var my = My()
let keyName = "level"
override init() {
super.init()
my.addObserver(self, forKeyPath: keyName, options: [.New, .Old], context: nil)
my.level += 2 // 1回目の変更
my.level += 7 // 2回目の変更
}
deinit {
my.removeObserver(self, forKeyPath: keyName)
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
print("Lv UP!!")
print("change:", change) // for Debug
}
}
class My: NSObject {
dynamic var level = 1
}
let p = Person()
必要なことは
- My クラスの level というプロパティを監視するために My クラスの中で dynamic をつけて宣言します。
- addObserver, removeObserver の引数である forKeyPath にはプロパティの名前を渡してあげます。(ここでは "level" となります)
このコードでは addObserver の引数である options に .New と .Old を渡してますが、これらはそれぞれ変更後のプロパティの値、変更前のプロパティの値を辞書として保存ということなります。今回プロパティの変更を2度行っています。それを踏まえて実行結果を見てみましょう。
Lv UP!!
change: Optional(["old": 1, "new": 3, "kind": 1])
Lv UP!!
change: Optional(["old": 3, "new": 10, "kind": 1])
old をキーとして変更前の値が保存されており、 new をキーとして更新された値が保存されていることが分かりますね!
#もっと簡単に行う
Swift ではプロパティで willSet, didSet を使うことで、もっと簡単にできます。
kvo2.swift
import Foundation
class Person: NSObject {
var my = My()
override init() {
super.init()
my.level += 2 // 1回目の変更
my.level += 7 // 2回目の変更
}
}
class My: NSObject {
var level: Int = 0 {
willSet {
print("Before")
print("Lv UP!!", level)
}
didSet {
print("After")
print("Lv UP!!", level)
}
}
}
let p = Person()
変更前の値を得るのは willSet で、変更後は didSet になります。
実行結果はこのようになります。
Before
Lv UP!! 0
After
Lv UP!! 2
Before
Lv UP!! 2
After
Lv UP!! 9
感想:
書き方をいくつか知っているとソースコードを読むときに役に立ちますね‼︎