50
47

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SwiftでKVO(Key-Value Observing)を行う

Posted at

#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()

必要なことは

  1. My クラスの level というプロパティを監視するために My クラスの中で dynamic をつけて宣言します。
  2. 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

感想:
書き方をいくつか知っているとソースコードを読むときに役に立ちますね‼︎

50
47
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
47

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?