[ Swift ] KVC(Key-Value-Coding), KVO(Key-Value-Observing)

안녕하세요 🐶
빈 지식 채우기의 비니🙋🏻‍♂️ 입니다.

오늘은 KVCKVO 대해 알아보는 시간을 가지겠습니다.

 

1.  개요

Objective C를 개발하다가 Swift로 넘어오면 참 편한 부분이 많습니다.

예를 들어 객체 선언 후 프로퍼티나 메서드를 접근을 하였던 Objective c면

. ( 닷 ) 을 써서 바로 접근이 가능한 Swift...

물론 해당 변수가 특정 객체임을 선언해야하는건 마찬가지지만요..ㅎㅎ

 

이처럼 참으로 개발자에게 친절한 Swift에서

오늘 다뤄볼 내용은 아래와 같습니다.

KVO : Key-Value-Observing

KVC : Key-Value-Coding

단어만 보면 저게 뭐지..? 싶을텐데 의외로 자기도 모르게 쓰고 계신 분들이 많을 거라 생각됩니다.

일단 난 안써봄 ㅎㅎ

 

자자자 그럼~.~ 자세한 설명 및 예시로 확인해보죠! :)

 

2.  KVC ( Key-Value-Coding )

Key 혹은 KeyPath를 통해 간접적으로 데이터를 가져오거나 수정하는 방법이다.
Key는 String이며, 일반적으로 객체 내의 정의된 메서드나 프로퍼티의 이름이 된다.

설명만 보면 무슨 내용이지..? 싶은데 자세한 내용은 소스를 통해 알아보도록 하겠슴돠! :-)

struct Body {
    var age: String
}

struct Person {
    var body: Body
}

let body = Body(age: "29")	// (1)
let person = Person(body: body)
let body = person[keyPath: \.body]	// (2)
let age = person[keyPath: \.body.age]	// (3)
print(age) // 28

person[keyPath: \.body.age] = "30"	// (4)
print(age) // 30
  1. Body 및 Person 인스턴스 생성
  2. \.body와 같은 KeyPath 방식으로 값 접근
  3. \.body.age 를 통해 age 값 접근
  4. \.body.age 를 통해 age 값 접근 후 값 변경

위와 같은 방식으로 \.body.age 와 같은 KeyPath는 생성해서 반복적으로 사용이 가능합니다.

 

KeyPath에는 여러 종류가 존재합니다.

  • AnyKeyPath : 타입이 지워진 KeyPath
  • PartialKeyPath : 부분적으로 타입이 지워진 KeyPath
  • KeyPath : Read-only KeyPath. 만약 let 프로퍼티에 접근할 경우 이를 사용해야함.
  • WritableKeyPath : value type 인스턴스에 사용 가능한 KeyPath. 변경 가능한 모든 프로퍼티에 대한 read & write access 제공
  • ReferenceWritableKeyPath : class의 인스턴스에 사용 가능 가능한 KeyPath. 변경 가능한 모든 프로퍼티에 대한 read & write access 제공.

 

3.  KVO ( Key-Value-Observing )

객체의 프로퍼티에 대한 변경사항을 다른 객체에 알리기 위해 사용된다.
NSObject를 상속받고 Observing을 하려난 프로퍼티에 @objc 속성과 dynamic 키워드를 추가한다.

KVO도 바로 예시를 통해 알아보도록 합시다! :-)

class Body: NSObject {	// (1)
    @objc dynamic var age: String	// (2)
    
    init(age: String) {
        self.age = age
    }
}
  1. KVO를 사용할 Body 클래스에 NSObject를 채택한다.
  2. Observing을 하려는 프로퍼티에 @obj 와 dynamic 키워드를 추가한다.

위와 같이 클래스를 생성하였으면 Observer를 통해 값 변화를 추적할 수 있다.

var body = Body(age: "28")
body.observe(\.age, options: [.old, .new]) { (object, change) in  // (1)
    print(change.oldValue, change.newValue)	// (2)
}
body.age = "청주시"
  1. Body 인스턴스에 KeyPath 로 프로퍼티에 Observer를 추가할 수 있다.
  2. 이후 값의 변화가 일어나면 change 핸들러를 통해 oldValue, newValue가 출력됩니다.

Observer의 options에는 여러 종류가 존재합니다.

  • old : 바뀌기 이전 값 호출
  • new : 바뀐 후의 값 호출
  • initial : 초기화할 때도 호출
  • prior : 이전 상태도 함께 전달

위와 같은 KVO는 두 객체간의 동기화가 쉽고 객체의 구현을 직접하지 않아도 인스턴스의 상태 변화를 체크할 수 있다는 장점이 있습니다.

 

이상으로 KVC(Key-Value-Coding), KVO(Key-Value-Observing) 포스팅을 마치겠습니다.
틀린 부분이나 궁금한 사항은 댓글 남겨주세요~

 


참고

반응형