key-value Observing의 약자로 Cocoa programming 패턴.
A객체에서 B객체의 프로퍼티가 변화됨을 감지할 수 있는 구조로 객체와 객체 사이에 관계를 다룬다.
Model과 View사이처럼 앱의 분리된 부분 사이에 변화를 주고받는데 유용하다.
이를 사용하기 위해 NSObject를 상속받아야 한다.
class Person: NSObject {
@objc dynamic var age: Int
init(age: Int) {
self.age = age
}
func passOneYear() {
self.age += 1
}
}
다음과 같이 NSObject를 상속받는 Person class를 생성해줬습니다.
즉, 상속을 받아야 하므로 value 타입인 struct, enum은 안되고 class만 가능합니다.
observe하려는 프로퍼티에 @objc attribute와 dynamic modifier를 추가해야 합니다.
let observer = person.observe(\.age, options: [.old, .new]) { object, value in
print("올해 나이는 \(value.newValue!)")
}
for _ in 0..<3 {
person.passOneYear()
}
// 올해 나이는 27
// 올해 나이는 28
// 올해 나이는 29
KeyPath를 사용하여 프로퍼티 KeyPath에 Observer를 추가할 수 있습니다.
위와 같이 observe를 등록해놓고 passOneYear()를 호출하면 새로운 값을 관찰할 수 있습니다.
person.observe(\.age, options: [.old, .new]) { object, value in
print("올해 나이는 \(value.newValue!)")
}
다음처럼 인스턴스를 새로 생성해주지 않으면 동작을 안합니다.. 왜그런건지는 잘 모르겠습니다.
또한 옵션을 설정하지 않고 observe하면 value로 넘어온 값에 newValue, oldValue도 nil로 넘어오게 됩니다.
NSKeyValueObservedChange<Int>(kind: __C.NSKeyValueChange, newValue: nil, oldValue: nil, indexes: nil, isPrior: false)
NSKeyValueObservedChange<Int>(kind: __C.NSKeyValueChange, newValue: nil, oldValue: nil, indexes: nil, isPrior: false)
NSKeyValueObservedChange<Int>(kind: __C.NSKeyValueChange, newValue: nil, oldValue: nil, indexes: nil, isPrior: false)
장점
단점
프로퍼티 옵저버가 있어서 한번도 사용해보지 못했는데 어디서 쓰는지는 잘 모르겠습니다..
https://medium.com/@Alpaca_iOSStudy/delegation-notification-그리고-kvo-82de909bd29