• 특정 키 값의 변화를 감지하기 위한 기능
• 객체의 프로퍼티 변경사항을 다른 객체에 알리기 위해 사용하는 코코아 프로그래밍 패턴이다.
• Model과 View 같이 논리적으로 분리된 파트간의 변경사항을 전달하는데 유용하다.
• 타입 정의 외부에서 obsever를 추가할 때 사용
KVO를 사용하려면, NSObject
를 상속해야한다. (순수 스위프트 코드 작성이 어려움)
상속을 받아야 하기 때문에, Class
에서만 사용이 가능하다.
또, observe
하려는 프로퍼티에 @objc attribute
와 dynamic modifier
를 추가해야 한다.
☑️ dynamic modifier
이 선언된 부분에 한해 Objective-C 런타임 방식을 사용하겠다는는 것이고, 런타임 시점에 호출해야 할 특정 메소드의 구현을 결정하는 것이다.
모델 객체에서 값이 변경되었을 경우, 변경된 값을 UI에 반영해야한다.
이때 컨트롤러가 모델 객체에 Observing
을 도입, 델리게이트에 메세지를 보내 처리하게 하는 것이다.
class Person: NSObject {
@objc dynamic var name: String
init(name: String) {
self.name = name
}
}
var person = Person(name: "JEE")
person.observe(\.name, options: [.old, .new]) { (object, change) in
print("Name changed from \(change.oldValue) to \(change.newValue)")
}
person.name = "도리" // Name changed from Optional("JEE") to Optional("도리")
프로퍼티 값이 JEE
에서 도리
로 변경되어, Observer
의 change handler
가 호출 ➡️ handler
내의 oldValue
와 newValue
를 가져올 수 있게 된다.
또, Option 에는 예시에 사용 된 old
/new
말고도 initial
/ prior
가 있다.
Option | 설명 |
---|---|
old | 변경 전 값 |
new | 변경 후 값 |
initial | Observer 등록 전 handler 호출 시 (newValue로 들어감) |
prior | 변경 전,후 상태 모두 파악시 |
var person = Person(name: "JEE")
person.observe(\.name, options: [.old, .new, .initial]) { (object, change) in
print("Name changed from \(change.oldValue) to \(change.newValue)")
} // Name changed from nil to Optional("JEE")
var person = Person(name: "JEE")
person.observe(\.name, options: [.old, .new, .prior]) { (object, change) in
print("Name changed from \(change.oldValue) to \(change.newValue)")
}
person.name = "도리"
// Name changed from Optional("JEE") to nil
// Name changed from Optional("JEE") to Optional("도리")
내가 짠 코드가 아닌, 다른 사람 혹은 외부 라이브러리에서 정의한 타입이라면 내부 소스를 마음대로 변경할 수 없다.
그럴때, 그 타입의 값 변화를 KVO 방식으로 관찰할 수 있다. (상속이나 코드의 변경 없이)
참고문서
1. https://zeddios.tistory.com/1220
2. https://www.zehye.kr/ios/2020/03/19/11iOS_KVO/