Key-path(키 경로)는 객체의 속성에 대한 "참조"를 통해 안전하게 접근할 수 있는 메커니즘입니다. 이것은 속성에 대한 완전한 type-safe 접근을 제공합니다:
struct Person { var name: String var age: Int } let kp = \Person.name let john = Person(name: "John", age: 30) print(john[keyPath: kp]) // "John"
WritableKeyPath는 속성을 읽기만 하는 것이 아니라 속성을 변경할 수도 있게 해줍니다:
var person = Person(name: "Foo", age: 22) let namePath: WritableKeyPath<Person, String> = \Person.name person[keyPath: namePath] = "Bar"
사용법:
세부 사항:
WritableKeyPath의 경우 객체(구조체)는 var 여야 합니다.질문: "일반 KeyPath를 통해 클래스 속성을 변경할 수 있나요 (아니면 WritableKeyPath가 필요하나요)? KeyPath와 ReferenceWritableKeyPath는 어떻게 다른가요?"
답변: key path를 통해 속성 값을 변경하려면 WritableKeyPath가 필요합니다. 클래스의 경우, 참조 유형의 key-path에 대해 속성을 변경할 수 있도록 하는 ReferenceWritableKeyPath 또한 존재합니다.
class User { var score = 0 } let user = User() let path: ReferenceWritableKeyPath<User, Int> = \User.score user[keyPath: path] = 42 // OK
이야기
큰 프로젝트에서 table-driven UI에서 일반 KeyPath와 WritableKeyPath를 혼동하여 KeyPath를 통해 모델의 속성을 변경하려 하여 runtime 예외가 발생했습니다.
이야기
제너릭 폼 생성 시 KeyPath를 값 바인딩에 사용했지만, 메소드를 keypaths로 리플렉션하려고 시도하여 컴파일 불가능 및 코드 복잡성이 증가했습니다.
이야기
개발자가 클래스에 대해 ReferenceWritableKeyPath를 추가하는 것을 잊어서 UI와 데이터 모델 간의 양방향 바인딩이 방해받았습니다: UI에서 값이 업데이트되었지만 모델은 이전 값을 유지했습니다.