관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] KVC (Key Value Coding), KVO (Key Value Observing), value(forKey:), setValue(_:forKey:) 개념 본문

iOS 기본 (swift)

[iOS - swift] KVC (Key Value Coding), KVO (Key Value Observing), value(forKey:), setValue(_:forKey:) 개념

jake-kim 2022. 5. 24. 22:33

Key의 개념

  • 스위프트의 KeyPath, KVC, KVO 자꾸나오는 Key의 개념은?
    • 문자열(Key)를 의미하고 이 key값을 통해 인스턴스의 프로퍼티 값(Value)에 간접적으로 접근하게 해주는 Objective-C에서 나온 개념

KVC (Key Value Coding)

  • 인스턴스의 프로퍼티에 접근할 때 key값인 문자열로 접근하는 방법
  • KVC는 Objective-C 런타임에 의존하므로 프로퍼티 앞에 @objc 어노테이션을 붙여서 사용
  • 단, Objective-C의 것이기 때문에 NSObject가 가지고 있으므로 NSObject의 서브클래스여야 가능

KVC 예제

  • KVC를 사용하기위해서 NSObject를 서브클래싱하고 @objc를 붙인 모델 정의
class Person: NSObject { // NSObject 서브클래싱
  @objc var name: String? // @objc 어노테이션
}
  • value(forKey:)로 name 프로퍼티의 값을 가져오고, setValue(_:forKey:)로 프로퍼티의 값을 수정
let person = Person()
person.value(forKey: "name") // nil
person.setValue("jake", forKey: "name")
person.value(forKey: "name") // "jake"

KVO (Key Value Observing)

  • KVC와 같이 Key값을 가지고 프로퍼티에 접근하는데, 이때 observing할 수 있는 방법
  • 프로퍼티 키워드에 @objc dynamic 을 붙여서 사용
class Person2: NSObject { // NSObject 서브클래싱
  @objc dynamic var name: String? // @objc dynamic 어노테이션
}
  • name이 변경될때마다 특정 작업을 수행하기 위해서 name을 observing하려면, observe(_:options:changeHandler)를 정의

person2.observe(\.name, options: [.old, .new]) { instance, change in
  print(change.oldValue, change.newValue)
}
person2.name = "fix" // 위에서 Optional(nil) Optional(Optional("fix")) 출력

KVO의 핵심

  • KVO는 willSet, didSet과 굉장히 유사
// willSet, didSet

class Person {
  var age = 1 {
    willSet { print(newValue) }
    didSet { print(oldValue) }
  }
}
  • 차이
    • willSet, didSet은 프로퍼티가 선언된 곳에서 같이 정의
    • KVO는 프로퍼티에 직접 정의하지 않아도 외부에서 추가하여 사용이 가능 (프로퍼티에 특정 성격을 추가하는데 자유로운 장점)
    • KVO를 사용하려면 struct여야하고, @objc dynamic이어야 하는 단점이 존재
    • dynamic을 붙이게되면 dynamic dispatch를 실행하게 되므로 성능 저하

* static dispatch, dynamic dispatch 개념은 이전 포스팅 글 참고

 

* 전체 코드: https://github.com/JK0369/ExKeyPath

* 참고

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueCoding/index.html

Comments