KVO란,
Object의 properties의 변경을 다른 Object에 알리기 위한 Cocoa programming pattern
NSObject를 상속한 Object에서만 KVO 사용가능하다.
또한, NSObject에 KVO를 위한 기본적인 methods가 잘 구현되어 있기 때문에 Override 할 필요가 없다.
KVO in Swift
우선, KVO를 사용하기 위해 NSObject를 상속 하여야 한다.
또한, Obeserve(관찰)할 property에 대해
@objc attribute와 dynamic modifier를 추가한다.
class Address: NSObject {
@objc dynamic var cityName: String
init(cityName: String) {
...
}
}
class Person: NSObject {
var name: String
@objc dynamic var address: Address
var myObserver: NSKeyValueObservation?
init(name: String, address: Address) {
...
}
}
우선 Person class내부의 address의 cityName property의 변화를 Observe할 것이기 때문에
address와 Address클래스 내부의 cityName에
@objc attribute와 dynamic modifier를 추가한다.
dynamic modifier는 Objective-C runtime 방식을 사용하겠다는 것이다.
이제 Observe를 구현해보자
observe를 생성 할때
observe(_:options,:changeHandler:) 를 통해 생성한다.
class Person: NSObject {
var name: String
@objc dynamic var address: Address
var myObserver: NSKeyValueObservation?
init(name: String, address: Address) {
self.name = name
self.address = address
super.init()
self.myObserver = observe(\.address.cityName,
options: [.old, .new]) { object, change in
print("\(change.oldValue)에서 \(change.newValue)로 바뀌었습니다.")
}
}
}
keyPath를 통해 지정한 위치의 property의 변화를 Observe(관찰)하게 된다.
changeHandler에서 변한 값을 handler할 수 있다.
let address = Address(cityName: "seoul")
let person = Person(name: "Jung", address: address)
let referenceWritableKeypath = \Person.address.cityName
person[keyPath: referenceWritableKeypath] = "busan"
//Optional("seoul")에서 Optional("busan")로 바뀌었습니다.
options는 생략이 가능한대, 변경이 필요 없을때, 생략하면 된다.
self.myObserver = observe(\.address.cityName) { object, change in
print("\(change.oldValue)에서 \(change.newValue)로 바뀌었습니다.")
}
이렇게 생략하게 되면
let address = Address(cityName: "seoul")
let person = Person(name: "Jung", address: address)
let referenceWritableKeypath = \Person.address.cityName
person[keyPath: referenceWritableKeypath] = "busan"
//nil에서 nil로 바뀌었습니다.
변화를 관찰 하지 않기 때문에 nil로 나오게 된다.
그외에도 options에는
- new
- old
- initial
- prior
4가지를 제공해준다.
initial의 경우에는 초기화 시점부터 값의 변화를 알고 싶을 때 사용하고,
prior은 이전의 상태까지 한번에 알고 싶은 경우에 사용한다.
장단점
장점
MVC pattern에서 controller는 view와 model의 변화를 관찰 해야 할때, 사용할 수 있다.
keyPath를 사용하여, 계층적인 객체의 프로퍼티도 쉽게 관찰 할 수 있다.
Controller의 경우 Model를 바라보게 됨. 또한, View는 Model의 관찰을 Controller를 통해서 함.
단점
objective-c의 runtime에 의존적이게 된다.
Reference
'iOS > Swift' 카테고리의 다른 글
[Swift] KVO, Delegate and Notification (2) | 2022.10.08 |
---|---|
[Swift] Notification (0) | 2022.10.08 |
[Swift] Delegate (0) | 2022.10.07 |
[Swift] KVC (Key-Value-Coding) (1) | 2022.10.05 |
[Swift] Subscript (4) | 2022.10.05 |