KVO

hoBahk·2021년 10월 27일
0

KVO

기본 설명

  • KVO는 Key-Value-Observer의 약자입니다.
  • KVO를 사용하려면 NSObect를 상속해야합니다.
    -> Objective-C 런타임에 의존하게 됩니다.
  • 객체의 변경사항을 다른 객체 알리기 위해 사용합니다.
  • 코코아 프로그래밍 패턴
  • Model의 프로퍼티가 변경될 때 ViewController로 전달 할 때 사용하는 것처럼 논리적으로 분리된 것(예: MVC(Model, view, Controller))끼리 변경사항을 알리는데에 사용합니다.

사용법

  1. NSObject를 상속한 클래스를 만들어 줍니다.
  • 변경사항을 전달해줄 프로퍼티에 @objc attribute와 dynamic modifier를 추가합니다.
class SooSan: NSObject {
    @objc dynamic var shirimp: Int

    init(shirimp: Int){
        self.shirimp = shirimp
    }
}
  1. Observer를 정의 해줍니다.
var hoonHoon = SooSan(shirimp: 100)

let kvo = hoonHoon.observe(\.shirimp, options: ([.old, .new])) { (object, change) in
    print(change.oldValue, change.newValue)
}

hoonHoon.shirimp = 120
  • \.shirimp: keyPath를 사용하여 observer에 프로퍼티를 지정해줍니다.
  • options에는 old, new, initial, prior 4가지 값이 들어갈 수 있습니다.
    - old는 변경되기 전의 값을 나타냅니다.
    - new는 변경된 값을 나타냅니다.
    - initial은 프로퍼티를 초기화 할 때도 observerHandler를 실행할 것인지 지정해주는 것입니다.
    - prior는 프로퍼티가 변경되는 것을 좀 더 세분화?해서 핸들러를 불러 옵니다.

initial

초기화 할 때와 값이 변경될 때 모두 핸들러가 호출됩니다.

var hoonHoon = SooSan(shirimp: 100) //초기화

let kvo = hoonHoon.observe(\.shirimp, options: ([.old, .new, .initial])) { (object, change) in
    print(change.oldValue, change.newValue)
}

hoonHoon.shirimp = 120 //값 변경

//nil Optional(100)
//Optional(100) Optional(120)

prior

초기화 할 때 핸들러가 호출되지 않았는데 두 번 호출이 됐습니다.
prior은 이전의 상태도 같이 줍니다.
값이 변경되기 위해 초기화 하는 순간 100은 oldValue가 됐고 newValue는 nil이 된 상태를 알려줍니다.

var hoonHoon = SooSan(shirimp: 100)

let kvo = hoonHoon.observe(\.shirimp, options: ([.old, .new, .prior])) { (object, change) in
    print(change.oldValue, change.newValue)
}

hoonHoon.shirimp = 120

//Optional(100) nil
//Optional(100) Optional(120)

아래 처럼 object를 통해 shirimp의 값을 확인 하면 이전값과 현재 값이 같이 출력이 됩니다.
이것을 보면 change의 oldValue, newValue는 옵셔널이고 object에서 접근해서 가져오면 옵셔널이 아닌 값으로 가져오는 것을 알 수 있네요!
oldValue와 newValue는 위의 예제들 처럼 값을 가지지 않을 수 있어서 옵셔널로 정의 되어 있고, object는 각 프로퍼티에 따라서 정해지겠네요! 현재 shirimp는 Int값이어서 같은 Int 값으로 정의됩니다.

var hoonHoon = SooSan(shirimp: 100)

let kvo = hoonHoon.observe(\.shirimp, options: ([.old, .new, .prior])) { (object, change) in
    print(object.shirimp)
}

hoonHoon.shirimp = 120

//100
//120

prior를 options에 넣어 주면 isPrior 프로퍼티를 사용하여 이전값인지 확인할 수 있습니다. 이전값이면 true 현재값이면 false가 반환됩니다.

var hoonHoon = SooSan(shirimp: 100)

let kvo = hoonHoon.observe(\.shirimp, options: ([.old, .new, .prior])) { (object, change) in
    print(object.shirimp)
    print(change.isPrior)
}

hoonHoon.shirimp = 120

//100
//true
//120
//false

KVO 장단점

장점

  1. KVO를 사용하면 논리적으로 분리된 것(ex) MVC: Model, view, Controller)끼리 변경사항을 알릴 수 있어 동기화가 가능합니다.
  2. oldValue(이전 값), newValue(현재 값)를 알 수 있습니다.
  3. KeyPath를 사용하여 프로퍼티를 observing하기 때문에 Nested프로퍼티도 관찰할 수 있습니다.
  4. 라이브러리의 프로퍼티의 변경사항을 알고 싶을 때 사용하면 좋습니다. BUT!! 해당 클래스가 NSObject를 상속하고 있어야 하며 해당 프로퍼티에 @objc dynamic이 있어야 합니다..

단점

  1. NSObject를 상속해야 하므로, Object-C 런타임에 의존하게 됩니다.
profile
호박에 줄 그어서 수박 되는 성장 드라마

0개의 댓글