Key-value observing을 알아보자.
Overview
Key-value observing 은 특정 객체의 프로퍼티 값의 변화를 다른 객체에 알리기 위해 사용되는 Cocoa 프로그래밍 패턴이다. 이는 model과 view 처럼, 앱에서 논리적으로 분리된 요소 사이의 커뮤니케이션을 위해 사용된다. KVO는 NSObject
를 상속받은 클래스에서만 사용할 수 있다.
Annotate a Property for Key-Value Observing
KVO를 통해 observe 하길 월하는 프로퍼티는 @objc
속성과 dynamic
식별자를 함께 작성해야 한다. 다음의 코드는 observe 될 수 있는 myDate
프로퍼티가 포함된 MyObjectToObserve
클래스를 정의한다.
class MyObjectToObserve: NSObject {
@objc dynamic var myDate = NSDate(timeIntervalSince1970: 0) // 1970
func updateDate() {
myDate = myDate.addingTimeInterval(Double(2 << 30)) // Adds about 68 years.
}
}
Define an Observer
Observer 클래스의 인스턴스는 하나 이상의 프로퍼티의 변화에 대한 정보를 관리한다. Oberver을 생성할때, observe 할 프로퍼티에 대한 참조인 key path와 함께, observe(_:options:changeHandler:)
를 호출하면서 observation을 시작한다.
다음의 예제에서 \.objectToObserve.myDate
key path는 MyObjectToObserve
의 myDate
프로퍼티를 참조한다.
class MyObserver: NSObject {
@objc var objectToObserve: MyObjectToObserve
var observation: NSKeyValueObservation?
init(object: MyObjectToObserve) {
objectToObserve = object
super.init()
observation = observe(
\.objectToObserve.myDate,
options: [.old, .new]
) { object, change in
print("myDate changed from: \(change.oldValue!), updated to: \(change.newValue!)")
}
}
}
NSKeyValueObservedChange
인스턴스의 프로퍼티 oldValue
와 newValue
를 사용하여 observe 하는 프로퍼티의 변경사항을 확인할 수 있다.
만약 어떻게(how) 프로퍼티가 변했는지 알 필요 없다면, option
파라미터를 생략할 수 있다. option
파라미터를 생략하면 프로퍼티의 변경 전후의 값을 저장하지 않고, oldValue
와 newValue
는 nil
이 된다.
Associate the Observer with the Property to Observe
Observe 할 프로퍼티와 그것의 observer를 결합할 수도 있다.
let observed = MyObjectToObserve()
let observer = MyObserver(object: observed) // 객체 전달
Respond to a Property Change
oberved
와 같이 key-value observing을 사용하기 위해 설정된 객체들은 프로퍼티의 변화를 자신의 oberver에게 알린다. 아래의 예제코드를 보면 myDate
프로퍼티는 updateDate
메소드가 호출되면서 값이 변한다. 이 메소드 호출은 자동적으로 observer의 changeHandler
를 일으킨다.
observed.updateDate() // Triggers the observer's change handler.
// Prints "myDate changed from: 1970-01-01 00:00:00 +0000, updated to: 2038-01-19 03:14:08 +0000"
앞서 정의한 changeHandler
에 의해 프로퍼티의 변경 전후의 값이 출력된다.