728x90
반응형
야곰 스위프트 프로그래밍 책을 읽으며 기억해둘 문법을 정리합니다.
프로퍼티
타입 프로퍼티
각각의 인스턴스가 아닌 타입 자체에 속하는 프로퍼티, 타입 자체에 영향을 미친다
저장 타입 프로퍼티 → 변수 또는 상수 선언
연산 타입 프로퍼티 → 변수로만 선언
저장 타입 프로퍼티 → 반드시 초깃값 설정, 지연 연산, 지연 저장 프로퍼티와는 조금 다르게 다중 스레드 환경이라고 하더라도 단 한 번만 초기화된다는 보장을 받는다.
코드
class AClass { // 저장 타입 프로퍼티 static var typeProperty: Int = 0 // 저장 인스턴스 프로퍼티 var instanceProperty: Int = 0 { didSet { // Self.typeProperty는 // AClass.typeProperty와 같은 표현이다 Self.typeProperty = instanceProperty + 100 } } // 연산 타입 프로퍼티 static var typeComputedProperty: Int { get { return typeProperty } set { typeProperty = newValue } } } AClass.typeProperty = 123 let classInstance = AClass() classInstance.instanceProperty = 100 print(AClass.typeProperty) // 200 print(AClass.typeComputedProperty) // 200
키 경로
프로퍼티의 위치만 참조하도록 할 수 있는 방법, 키 경로(Key Path) 활용
키 경로 타입은
AnyKeyPath
라는 클래스로부터 파생제일 많이 확장된 키 경로 타입은
WritableKeyPath<Root, Value>
와ReferenceWritableKeyPath<Root, Value>
타입WritableKeyPath<Root, Value>
타입은 값 타입에 키 경로 타입으로 읽고 쓸 수 있는 경우에 적용ReferenceWritableKeyPath<Root, Value>
타입은 참조 타입, 즉 클래스 타입에 키 경로 타입으로 읽고 쓸 수 있는 경우에 적용키 경로는
\
,타입
,마침표
경로로 구성 (ex.\타입이름.경로.경로
)키 경로를 잘 활용하면 타입 간의 의존성을 낮추는 데 많은 도움을 준다
코드
// 키 경로 타입의 타입 확인 class Person { var name: String init(name: String) { self.name = name } } struct Stuff { var name: String var owner: String } print(type(of: \Person.name)) // ReferenceWritableKeyPath<Person, String> print(type(of: \Stuff.name)) // WritableKeyPath<Stuff, String> // 키 경로 타입의 경로 연결 let keyPath = \Stuff.owner let nameKeyPath = keyPath.appending(path: \.name)
// keyPath 서브스크립트와 키 경로 활용 class Person { let name: String init(name: String) { self.name = name } } struct Stuff { var name: String var owner: Person } print(type(of: \Person.name)) print(type(of: \Stuff.name)) let yagom = Person(name: "yagom") let hana = Person(name: "hana") let macbook = Stuff(name: "MacBook Pro", owner: yagom) var iMac = Stuff(name: "iMac", owner: yagom) let iPhone = Stuff(name: "iPhone", owner: hana) let stuffNameKeyPath = \Stuff.name let ownerkeyPath = \Stuff.owner // \Stuff.ower.name과 같은 표현이 된다 let ownerNameKeyPath = ownerkeyPath.appending(path: \.name) // 키 경로와 서브스크립트를 이용해 프로퍼티에 접근하여 값을 가져온다 print(macbook[keyPath: stuffNameKeyPath]) // MacBook Pro print(iMac[keyPath: stuffNameKeyPath]) // iMac print(iPhone[keyPath: stuffNameKeyPath]) // iPhone print(macbook[keyPath: ownerNameKeyPath]) // yagom print(iMac[keyPath: ownerNameKeyPath]) // yagom print(iPhone[keyPath: ownerNameKeyPath]) // hana // 키 경로와 서브스크립트를 이용해 프로퍼티에 접근하여 값을 변경한다 iMac[keyPath: stuffNameKeyPath] = "iMac Pro" iMac[keyPath: ownerkeyPath] = hana print(iMac[keyPath: stuffNameKeyPath]) // iMac Pro print(iMac[keyPath: ownerNameKeyPath]) // hana // 상수로 지정한 값 타입과 읽기 전용 프로퍼티는 키 경로 서브스크립트로도 값을 바꿀 수 없다
// 클로저를 대체할 수 있는 키 경로 표현 struct Person { let name: String let nickname: String? let age: Int var isAdult: Bool { return age > 18 } } let yagom: Person = Person(name: "yagom", nickname: "bear", age: 100) let hana = Person(name: "hana", nickname: "na", age: 100) let happy = Person(name: "happy", nickname: nil, age: 3) let family = [yagom, hana, happy] // {$0.name}의 표현과 같은 역할을 수행한다 let names: [String] = family.map(\.name) // ["yagom", "hana", "happy"] let nicknames: [String] = family.compactMap(\.nickname) // ["bear", "na"] let adults: [String] = family.filter(\.isAdult).map(\.name) // ["yagom", "hana"]
반응형
'Programming > Swift' 카테고리의 다른 글
[Swift] 문법 다시보기 - 인스턴스 생명 및 소멸, 접근제어 (0) | 2021.10.13 |
---|---|
[Swift] 문법 다시보기 - 메서드 (0) | 2021.10.13 |
[Swift] 문법 다시보기 - 구조체와 클래스의 차이 (0) | 2021.10.12 |
[Swift] 문법 다시보기 - 옵셔널, 클래스 (0) | 2021.10.11 |
[Swift] 문법 다시보기 - 함수 (0) | 2021.10.11 |