KVO observing using ViewController

Jeremy Park·2022년 9월 9일
0
post-thumbnail

왜 ViewController는 NSObject 상속을 받지않아도 돌아가는건가요?

ViewController가 상속하는 UIViewController, UiViewController가 상속하는 UIResponder가 NSObject를 상속받기 떄문입니다. (링크 참조)

MyLovelyViewController <- UIViewController <- UIResponder <- NSObject

ViewController를 KVO의 Observer로 사용해보자.

KVO는 Observer가 Object를 감시하는 개념이기 떄문에 아래의 이미지의 화살표 방향은 잘못됐습니다. 참고하시기 바랍니다.. 이미지 올리면서 KeyNote파일 삭제했거덩요...

위와같이 KVO는 NotificationCenter와는 달리 알림이 거쳐가는 중계 지점이 없는 점이 특징입니다. 따라서 개인적인 의견이지만 KVO는 하나의 Observer만을 사용할 떄 적합한 것 같습니다.

틀린 의견일 수 있다는 점 참고해주시면 감사하겠습니다.

1. Object to observe 지정

class MyObjectToObserve: NSObject {
    @objc dynamic var stock: [String: Int] = [
        "딸기": 10,
        "바나나": 10,
        "파인애플": 10,
        "키위": 10,
        "망고": 10
    ]
}

Object를 observing 하기 위해서는 NSObject에 @objc attribute와 dynamic declaration modifier를 붙여주어야 합니다.

공식문서의 정의를 살펴보면 dynamic은 항상 @objc와 사용한다고 이해할 수 있는데 일반 변수에 dynamic을 붙여주면 오류가 나지 않습니다. 뇌피셜을 펼쳐보자면 Swift 런타임에서 사용하겠다고 선언된 것으로 생각됩니다. 틀린 정보일 수 있습니다.

@objc dynamic을 붙여줬다면 object to observe 지정은 완료 됐습니다. 다음으로는 Observer를 만들어보겠습니다.

2. Observer 생성

위에서 언급했듯이 ViewController는 NSObject를 상속받기 때문에 아래와 같이 Observer를 담을 그릇으로써 사용될 수 있습니다.

class MyLovelyViewController: UIViewController {
    var observation: NSKeyValueObservation?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        observation = observe(\.MyobjectToObserve.stock,
                              options: [.old, .new],
                              changeHandler: { (object, changes) in
                              //실행할 코드
                              print("Data has been changed")
                              print("Data has been changed")
                              print("Data has been changed")
        })
    }
}
  1. 변수 observetion을 NSKeyValueObservation 옵셔널 타입으로 선언
    🌏 NSKeryValueObserving protocol

  2. viewDidLoad() 내부에 observation을 observer NSKeyValueObservation의 메소드인 observe()를 사용하여 정의해주면 끝입니다... 옵저빙하는 데이터가 변경될 떄마다 changeHandler내부의 코드가 실행되는 메커니즘입니다. 예시로 Label.text에 값을 할당하는 메소드를 넣어 observing object 값이 변경될 떄마다 Label.text도 업데이트 해주면 좋을 것 같습니다.

예제에서 사용하는 observe()메소드에 요구되는 프로퍼티들은 아래와 같습니다.

  • keyPath 🌏 NSKeyValueCoding , 🌏 Zedd KVC

    Observing 할 object의 주소(keyPath)를 간접적으로 나타냅니다.
    keyPath를 나타낼 때에는 역슬레시와 점이 꼭 들어가야합니다. \.

  • options 🌏 NSKeryValueObservingOptions

    • .new 변경된 후의 값을 가져오게 합니다.

    • .old 변경되기 전의 값을 가져오게 합니다.

    • .initial 보통 값이 변경된 후에만 changeHandler가 작동하는데 초기화시에도 작동하도록 합니다.

    • .priop newValue, oldValue 둘다 하나의 묶음으로 반환합니다.

      옵션이 필요없다면 빈 배열로 남겨주면 됩니다. 이떄 options은 nil이 됩니다.

  • changeHandler

    • (object, changes) in 현재 keyPath에 해당하는 값(object)과 가져온 값(changes)
    • 값에 변화가 일어난 후 실행할 코드를 넣는 곳

참고 링크

profile
IOS, Swift 공부합니다.

0개의 댓글