Key-Value Observing이란 객체의 프로퍼티 변경 사항을 다른 객체에 알리기 위해 사용하는 프로그래밍 패턴.
kvo는
Swift 상에서는 didSet이나 willSet 같은 것으로 충분히 대체가 가능할 것 같아 굳이 써야하나 싶은 패턴인 것 같다.
KVO: Key-Value Observing 이란?
Cocoa programming pattern you use to notify objects about changes to properties of other objects. It’s useful for communicating changes between logically separated parts of your app—such as between models and views. You can only use key-value observing with classes that inherit from NSObject.
- 객체의 프로퍼티의 변경사항을 다른 객체에 알리기 위해 사용하는 코코아 프로그래밍 패턴
- Model과 View와 같이 논리적으로 분리된 파트간의 변경사항을 전달하는데 유용함
- NSObject를 상속한 클래스에서만 KVO를 사용할 수 있음.
KVO 사용법
Set Property for Key-Value Observing
관찰할 프로퍼티 설정해주기
Mark properties that you want to observe through key-value observing with both the @objc attribute and the dynamic modifier.
class Company: NSObject {
@objc dynamic var president: String = "진양철"
func updatePresident(president: String) {
self.president = president
}
}
Define an Observer
When you create an observer, you start observation by calling the observe(_:options:changeHandler:) method with a key path that refers to the property you want to observe.
class CompanyObserver {
var observation: NSKeyValueObservation?
func observe(object: Company) {
observation = object.observe(\.president, options: [.old, .new]) { object, change in
print(change.oldValue, change.newValue)
}
}
deinit {
observation?.invalidate()
}
}
Respond to a Property Change
프로퍼티 변경 감지
다음과 같이 옵저버를 설정해준 후, 프로퍼티를 변경해주면 옵저버 실행이 잘 되는 걸 확인할 수 있다.
let company = Company()
let observer = CompanyObserver()
observer.observe(object: company)
company.updatePresident(president: "진도준") //회장: 진양철 -> 진도준
class Company: NSObject {
@objc dynamic var president: String = "진양철"
func updatePresident(president: String) {
self.president = president
}
}
class CompanyObserver {
var observation: NSKeyValueObservation?
func observe(object: Company) {
observation = object.observe(\.president, options: [.old, .new]) { object, change in
guard let oldValue = change.oldValue, let newValue = change.newValue else { return }
print("회장: \(oldValue) -> \(newValue)")
}
}
}
let company = Company()
let observer = CompanyObserver()
observer.observe(object: company)
company.updatePresident(president: "진도준") //회장: 진양철 -> 진도준
* 프로퍼티 옵저버 (willSet, didSet) 랑 비슷한 것 같은데? 라는 생각이 들었음.
프로퍼티 옵저버는 타입 정의 내부에 위치해야 하고, KVO는 타입 정의 외부에서 observer를 추가할 때 사용하는 거라고 한다.
즉, 자신이 정의한 타입의 경우 willset, didset 구현으로 더 편리하게 사용이 가능하지만, 외부 라이브러리를 사용한 경우에는 내부 소스를 변경할 수 없기 때문에 KVO를 활용해 프로퍼티 감시자처럼 사용할 수 있는 장점이 있다고 한다.
KVO 장단점
Advantages of using Key-Value Observing
- Multiple observers - there is no limitation on the number of subscribers. 다중 옵저버. 구독자 수에 제한이 없다
- no need to change the source code of the class under observation. 관찰 중인 클래스의 소스 코드를 변경할 필요가 없다.
(외부라이브러리 사용할 때 KVO가 유리하다면 관찰할 클래스가 NSObject로 만들어져있고 업데이트 코드가 사전에 다 구현이 되어 있는 상황에서만 가능한거 아닌가..?)
- very low coupling 매우 낮은 결합도. - the observed party doesn’t even know it’s being observed, the observing party’s knowledge is bounded by the name of the @property
- 관찰된 값의 가장 최근 값 뿐만 아니라 이전 값도 전달하도록 Notification을 구성할 수 있다.
Disadvantages of using Key-Value Observing
- One of the worst APIs across Cocoa.
- Each observer has to explicitly unsubscribe on deinit - otherwise crash is unavoidable. 각 옵저버는 명시적으로 구독을 취소해야 한다. 그렇지 않으면 충돌이 불가피.
- Relatively slow performance. 상대적으로 느린 성능.
이러면 굳이 쓸 이유가..? 의문.. ㅋㅋ
참고 :
https://developer.apple.com/documentation/swift/using-key-value-observing-in-swift
https://zeddios.tistory.com/1220
https://topic.alibabacloud.com/a/delegate-notificationkvo-pros-and-cons_8_8_31286426.html
https://nalexn.github.io/kvo-guide-for-key-value-observing/
https://nalexn.github.io/callbacks-part-1-delegation-notificationcenter-kvo/
'Swift iOS 앱 개발 > Swift' 카테고리의 다른 글
[Swift] protocol 프로토콜이란? (0) | 2023.01.03 |
---|---|
[Swift] 객체 간 소통 및 이벤트 전달 Delegate / NotificationCenter / KVO (0) | 2022.12.28 |
[Cocoa Design Pattern] Singleton Pattern (0) | 2022.12.22 |
[Cocoa Design Pattern] Delegation Pattern (0) | 2022.12.22 |
[Swift] Subscripts란? + String은 subscript로 접근이 안되는 이유 (0) | 2022.12.14 |