Swift) KVO

Publishing Date:2020-09-22

배경지식

iOS 앱을 작성하면서 수많은 객체가 생성되고 각자의 역할을 수행한다. 각 객체는 서로 연관되어 동작하면서도 객체지향의 원칙에 따라(이 경우 SRP?) 서로 종속되는 것을 지양해야 한다. 이 수많은 객체들이 서로의 기능을 침범하지 않은 채 조화롭게 작동하기 위해서는 대화(Communication)가 필요하다. 이 대화에 해당하는 세 가지 패턴이 바로 Delegation, Notification, 그리고 KVO이다. 이 세 가지 패턴은 각 객체가 서로에게 종속되지 않으면서 특정 이벤트가 발생하면 원하는 객체에게 알려줌으로써 상황에 맞는 처리를 할 수 있게 작용한다.
Delegation에 관해서는 여기서 확인할 수 있다.
Notification에 관해서는 여기서 확인할 수 있다.

KVO

Key Value Observing
다른 객체에게 객체 프로퍼티의 변화를 알리는(notify) 프로그래밍 패턴
MVC 패턴과 같이 논리적으로 분리된 파트간 커뮤니케이션을 위해 사용
NSObject를 상속한 class에서만 사용 가능

적용

  1. 프로퍼티 마킹
    NSObject를 상속한 클래스 안의 프로퍼티 중 KVO 패턴을 통해 Observe하고싶은 프로퍼티들에 @objc dynamic 키워드를 추가한다.
    class MyObjectToObserve: NSObject {
     @objc dynamic var myDate = NSDate(timeIntervalSince1970: 0) // 1970
     func updateDate() {
         myDate = myDate.addingTimeInterval(Double(2 << 30)) // Adds about 68 years.
     }
    }
    
  2. Observer 클래스 정의
    class MyObserver: NSObject {
     @objc var objectToObserve: MyObjectToObserve
     var observation: NSKeyValueObservation?
    
     init(object: MyObjectToObserve) {
         objectToObserve = object
         super.init()
    
         observation = observe(
             \.objectToObserve.myDate,
             options: [.old, .new]
         ) { object, change in
             print("myDate changed from: \(change.oldValue!), updated to: \(change.newValue!)")
         }
     }
    }
    
  3. Observer와 마킹한 프로퍼티 링크
    let observed = MyObjectToObserve()
    let observer = MyObserver(object: observed)
    
  4. 데이터 업데이트
    observed.updateDate() // Triggers the observer's change handler.
    // Prints "myDate changed from: 1970-01-01 00:00:00 +0000, updated to: 2038-01-19 03:14:08 +0000"
    

특징

Reference

애플 개발자 문서
세 디자인 패턴 비교

Comments