-
안녕하세요. 그린입니다🟢
이번 포스팅에서는 KeyPath에 대해 학습해보겠습니다🧑🏻💻
KeyPath?아.. 계속 영어로 치기 귀찮은 한국인이라 요기서부터 본문은 키패스라고 타이핑하겠습니다!
키패스를 왜 학습하게 되었나하면 Composable Architecture를 실무에서 사용하면서 하위 리듀서를 상위 리듀서에서 가져와
액션을 구현할때가 있습니다.
음.. 예를들어 모두 홈 모듈에 지도뷰 모듈도 있고 리스트 모듈도 있다고 쳤을때 지도뷰 모듈에서 어떤 에러가 발생하면
홈 모듈에서 얼럿을 띄워줘야 하는 경우를 가정할 수 있습니다.
그러니까 모듈간 종속을 보면 이렇게 되겠네요!
으.. 만들고 보니 징그럽지만 무튼 이렇습니다.
다양한 하위 모듈이 Home 모듈에 속해있죠?
이럴때 홈 모듈에서 하위 모듈의 상태를 가지는 동시에 홈 모듈의 상태도 가집니다.
그럴경우 해당 상태값을 부를때 키패스를 이용하는게 성능이나 그런 이점보다는 간결한 코드로 보였습니다! (제눈에는요👀)
그러해서! 키패스가 궁금해졌고 한번 맛보기로 이번 주제를 삼았습니다👏
그럼 정말 본격적?으로 키패스에 대해 알아보시죠📝KeyPath!
공식문서 ㄱㄱ
A key path from a specific root type to a specific resulting value type.
라고 하네요?
직역해보면 특정 루트 타입에서 특정 루트 결과 값 타입으로의 키경로!
굉장히 단순명료한 설명이네요.
키패스의 선언은 이렇습니다.
class KeyPath<Root, Value> : PartialKeyPath<Root>
루트 벨류 중요중요!
음.. 생각해보면 약간 포인터 느낌도 나네요.
프로퍼티의 참조값을 저장하는것 같아요.
아 대충 키패스가 뭐어떤 역할인지 알겠다!
근데 이게 왜 필요한거지? 뭐에 유용한걸까요?
KeyPath 사용
쉽게 생각해볼 수 있을것 같아요.
딕셔너리에서 키 값이 존재하지 않는다면? 벨류를 어떻게 가져오지?
키를 가지고 벨류를 가져오는 KVC 방식을 좀 더 간단하게 해보죠.
struct Info { var name: String var age: Int var isAlive: Bool } let green = struct(name: "GREEN", age: 100, isAlive: false) // 1 let nameOfGreen = green.name // 2 let nameOfGreen = green[keyPath: \.name]
이렇게 1번처럼 대부분 선언을 하죠
그런데 2번처럼 키패스로도 접근을 할 수 있다~~ 입니다!
그런데 키패스는 너무 익히 사용하던건데 흠.. 하 흠..? 너무 당연하게 익숙함에 속아버린느낌!
흠.. 더 알아보면서 익혀보도록 하겠습니다.
키패스를 생성하는 규칙은 간단합니다.
\Type.Property
타입과 프로퍼티로!! 어떤 타입에 어떤 프로퍼티인지 백슬래쉬로 경로를 나타냅니다.
KeyPath 종류
공식문서를 통해 살펴본 키패스 종류는 5개입니다.
1. AnyKeyPath
- 타입이 지워진 키패스
2. PartialKeyPath<Root>
- 부분적 타입이 지워진 키패스
- AnyKeyPath 상속
3. KeyPath<Root, Value>
- 계속 살펴본 키패스로 Read-only
- PartialKeyPath 상속
4. WritableKeyPath<Root, Value>
- 값 타입 인스턴스에서 읽기 쓰기가 가능
- KeyPath 상속
5. ReferenceWritableKeyPath<Root,Value>
- 클래스 인스턴스에서도 사용가능하며 모든 프로퍼티에 대해 읽기 쓰기가 가능
- WritableKeyPath 상속요렇게 살펴볼 수 있습니다!
이렇게 키패스를 간단히 살펴보았는데요 저는 지금까지는 확실히 키패스 짱짱! 이걸 못느끼고 아.. 이런게 있구나 하고 있었습니다.
그런데 어떠한 실마리를 우형 기술 블로그에서 조금 찾을 수 있었습니다🙋🏻♂️🙋🏻♂️🙋🏻♂️
KeyPath를 썼을때 차이?
보통 값 참조로 변수를 저장합니다.
그런 반면 키패스는 프로퍼티에 대한 참조입니다.
쉽게 말해 키패스는 프로퍼티를 가집니다.
즉 옵젝트죠!?
네 그런 차이가 있습니다🥲
swift 4.2에서 나온 dynamicMemberLookup이라는 기능과 같이 사용하면 좋다고 하는데
아직 그부분은 학습을 못했기에..😭
따로 또 학습해보도록 하겠습니다.
이렇게 많이 파고들진 못했지만 키패스를 소개할 수 있는 정도를 알아봤습니다!
뭔가 숙제가 더 많이 생긴듯한 이번 주제였고
저는 키패스를 \를 나타내서 쓰는게 더 복잡해보이는거 같은데 왜 저렇게 쓰는 코드가 더 나은건가? 등등에 대해서 의문점이 들었었어요.
보통 a.name이렇게 가잖아요?
근데 a[keyPath: \.name] 이렇게 쓰는게 뭔 이점이 있나 궁금해서 이걸 시작한거긴 하거든요.
그러면서 키패스를 본질적으로 다시보게 되었어요.
결론은 두개 선택입니다!
지금 간단한거야 가독성이 a.name이 더 낫지만 초반에 말했듯 하위 리듀서 모듈을 가져와 State에서 키패스로 접근할때 헷갈리지 않는 부분? 그런거라고 지금 이해가 되요.
어떻게 잘 활용되고 있는지 보여주면 좋았을것 같은데..
음.. ReactorKit에서 그런게 있던것 같은데 좀 더 공부하고 익혀서 다시 소개해보도록 하겠습니다🎉[참고자료]
https://developer.apple.com/documentation/swift/keypath
https://techblog.woowahan.com/2715/
'Swift' 카테고리의 다른 글
Method Swizzling (0) 2022.01.14 Swift - Markdown (2) 2021.10.20 Dictionary.init(uniqueKeysWithValues:) (0) 2021.08.31 순수함수와 사이드이펙트 (0) 2021.08.22 Safe Array (0) 2021.07.24