apple/Docs, iOS, Swift
Swift KeyPath 정리
lgvv
2024. 8. 28. 01:23
Swift KeyPath 정리
Realm의 @objc dynamic으로 사용하는 이유, property wrapper의 다채로운 활용 등 KeyPath를 이해하면 Swift 언어의 발전을 이해하는데 도움.
KeyPath란?
- KeyPath 표현식은 특정 타입의 속성(property) 또는 서브스크립트(subscript)를 참조.
- KeyPath 표현식은 주로 키-값 관찰과 같은 동적 프로그래밍 작업에서 사용.
- KeyPath 표현식은 다음과 같은 형태를 가짐.
사용 형태
\<#type name#>.<#path#>
샘플 코드
import SwiftUI
class Person: NSObject {
@objc var name: String
@objc var age: Int
@objc dynamic var hp: Int = 100
var mp: Int = 1 {
willSet { print(newValue) }
didSet { print(oldValue) }
}
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
struct KeyPathExampleView: View {
var body: some View {
VStack(spacing: 30) {
Button {
kvc()
} label: {
Text("kvc")
}
Button {
kvo()
} label: {
Text("kvo")
}
}
}
let person = Person(name: "John", age: 30)
func kvc() {
// KVC를 사용하여 값 가져오기
if let name = person.value(forKey: "name") as? String,
let age = person.value(forKey: "age") as? Int
{
print("Name: \(name) Age: \(age)") // 출력: Name: John
}
// KVC를 사용하여 값 설정하기
person.setValue(35, forKey: "age")
print(person.age) // 출력: 35
print(person[keyPath: \.age]) // 출력: 35
}
func kvo() {
person.observe(
\.hp,
options: [.initial, .old, .new, .prior]
) { person, observedChange in
if observedChange.isPrior {
print("About to change: \(String(describing: observedChange.oldValue))")
} else {
print("Changed from \(String(describing: observedChange.oldValue)) to \(String(describing: observedChange.newValue))")
}
}
person.hp = 20
person.mp = 10
}
}
#Preview {
KeyPathExampleView()
}
KeyPath를 사용하는 것과 직접 접근하는 것의 차이
직접접근
- 설명: 점 표기법을 사용하여 객체의 속성에 직접 접근. 이 방법은 가장 일반적인 방식으로, 컴파일 타임에 속성의 존재와 타입이 확정.
- 유연성: keyPath를 변수로 저장하거나 함수에 전달할 수 있음. 따라서 런타임에 어떤 속성에 접근할지 동적으로 결정할 수 있음.
- 활용 범위: 주로 복잡한 데이터 구조에서 여러 속성에 대해 동일한 연산을 적용해야 하거나, 속성을 동적으로 접근해야 하는 경우에 유용
KeyPath 접근
- 설명: KeyPath를 사용하여 객체의 속성에 접근하는 방식. 이 방법은 런타임에 KeyPath를 통해 속성에 간접적으로 접근할 수 있음. KeyPath는 경로를 나타내는 타입 안전한 객체.
- 유연성: keyPath를 변수로 저장하거나 함수에 전달할 수 있음. 따라서 런타임에 어떤 속성에 접근할지 동적으로 결정할 수 있음.
- 활용 범위: 주로 복잡한 데이터 구조에서 여러 속성에 대해 동일한 연산을 적용해야 하거나, 속성을 동적으로 접근해야 하는 경우에 유용.
(참고)