KVO (Key Value Observing)

Jee.e (황지희)·2022년 3월 23일
0
post-custom-banner

KVO(Key Value Observing)란 무엇인가?

• 특정 키 값의 변화를 감지하기 위한 기능
• 객체의 프로퍼티 변경사항을 다른 객체에 알리기 위해 사용하는 코코아 프로그래밍 패턴이다.
• Model과 View 같이 논리적으로 분리된 파트간의 변경사항을 전달하는데 유용하다.
• 타입 정의 외부에서 obsever를 추가할 때 사용


✅ 주의사항

KVO를 사용하려면, NSObject 를 상속해야한다. (순수 스위프트 코드 작성이 어려움)
상속을 받아야 하기 때문에, Class 에서만 사용이 가능하다.
또, observe 하려는 프로퍼티에 @objc attributedynamic 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 에서 도리 로 변경되어, Observerchange handler 가 호출 ➡️ handler 내의 oldValuenewValue 를 가져올 수 있게 된다.


또, Option 에는 예시에 사용 된 old /new 말고도 initial / prior 가 있다.

Option설명
old변경 전 값
new변경 후 값
initialObserver 등록 전 handler 호출 시 (newValue로 들어감)
prior변경 전,후 상태 모두 파악시


• initial 예시

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")

• prior 예시

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. 두 객체간의 동기화 (Ex. Model과 View 같이 분리된 파트간의 변경사항 전달)
  2. 내부 소스 변경 없이, 상태 변화에 대응할 수 있다.
  3. 변경 전/후 값을 파악할 수 있다.

✅ KVO 단점

  1. Objective-C 런타임에 의존 및 클래스만 구현 가능(NSObject 상속)
  2. dealloc될 때 옵저버를 지워줘야 한다.


﹖ 언제 사용해야 해 ﹖

내가 짠 코드가 아닌, 다른 사람 혹은 외부 라이브러리에서 정의한 타입이라면 내부 소스를 마음대로 변경할 수 없다.
그럴때, 그 타입의 값 변화를 KVO 방식으로 관찰할 수 있다. (상속이나 코드의 변경 없이)



참고문서
1. https://zeddios.tistory.com/1220
2. https://www.zehye.kr/ios/2020/03/19/11iOS_KVO/

profile
교훈없는 경험은 없다고 생각하는 2년차 iOS 개발자입니다.
post-custom-banner

0개의 댓글