메서드가 아닌 연산 프로퍼티를 사용하는 이유?
struct CoordinatePoint{
var x: Int
var y: Int
func oppositePoint() -> Self{
return CoordinatePoint(x: -x, y: -y)
}
mutating func setOppositePoint(_ opposite: CoordinatePoint){
x = -opposite.x
y = -opposite.y
}
}
struct CoordinatePoint{
var x: Int
var y: Int
var oppositePoint: CoordinatePoint{
**get** {
return CoordinatePoint(x: -x, y: -y)
}
**set(opposite)** {
x = -opposite.x
y = -opposite.y
}
}
}
이 경우에는 매개변수를 따로 표기하면 안됨
var oppositePoint: CoordinatePoint{
**get** {
return CoordinatePoint(x: -x, y: -y)
}
**set** {
x = -newValue.x //newValue.x로도 작성 가능
y = -newValue.y
}
}
}
willSet
didSet
프로퍼티의 값이 변경된 직후에 호출하는 메서드
didSet에 전달되는 전달인자는 프로퍼티가 변경되기 전의 값
매개변수의 이름을 따로 지정하지 않을 경우 oldValue 이름이 자동 지정됨
didSet 감시자 코드 블록 내붸서 oldValue 값을 참조하지 않거나 매개변수 목록에 명시저그로 매개변수를 적어주지 않을 경우 didSet 코드 블록은 실행되지 않음
클래스를 상속받았다면 기존의 연산 프로퍼티를 재정의하여 프로퍼티 감시자를 구현할 수도 있음
연산 프로퍼티를 재정의해도 기존의 연산 프로퍼티 기능(접근자, 설정자, get, set)은 동작함
static
키워드 사용//저장 타입 프로퍼티
static var typeProperty: Int = 0
//연산 타입 프로퍼티
static var typeComputedProperty: Int {
get ..
set ..
}
키 경로 타입
WritableKeyPath<Root, Value>
ReferenceWritableKeyPath<Root,Value>
키 경로는 역슬래시()와 타입, 마침표(.)로 구성
/타입이름.경로.경로.경로
class Person{
let name: String
}
struct Stuff{
var name: String
var owner: Person
}
let ssooya = Person(name: "ssooya")
let macbook = Stuff(name: "MacBook Pro", owner: ssooya)
let stuffNameKeyPath = \Stuff.name
let ownerkeyPath = \Stuff.owner
let ownerNameKeyPath = ownerkeyPath.appending(path: \.name) //\Stuff.owner.name과 같은 표현
print(macbook**[keyPath: stuffNameKeyPath]**) //MacBook Pro
print(macbook**[keyPath: ownerNameKeyPath]**) //ssooya
자신을 나타내는 키 경로인 \.self
를 사용하면 인스턴스 그 자체를 표현하는 키 경로가 됨
컴파일러가 타입을 유추할 수 있는 경우에는 키 경로에서 타입 이름을 생략할 수도 있음
스위프트 5.2버전부터 (SomeType) → Value
타입의 클로저를 키 경로 표현으로 대체하여 사용 가능
let ssooya: Person = Person(name: "ssooya", nickname: "a")
let soyun: Person = Person(name: "soyun", nickname: "b")
let park: Person = Person(name: "park", nickname: "c")
let family: [Person] = [ssooya, soyun, park]
let names: [String] = family**.map(\.name)** //["ssooya", "soyun", "park"]
mutating
키워드를 붙여서 해당 메서드가 인스턴스 내부의 값을 변경한다는 것을 명시해야 함struct LevelStruct{
var level: Int = 0
**mutating** func levelUp(){
level += 1
}
}
self 프로퍼티
인스턴스를 명확히 지칭하고 싶을 때 사용
값 타입 인스턴스 자체의 값을 치환할 수도 있음
클래스 인스턴스는 참조 타입이라서 self 프로퍼티에 다른 참조 할당 불가능
구조체나 열거형 등은 self 프로퍼티를 사용하여 자신 자체를 치환할 수 있음
class LevelClass{
var level: Int = 0
/* 오류 발생
func reset(){
self = LevelClass() -> self 프로퍼티 참조 변경 불가능
}
*/
}
struct LevelStruct{
var level: Int = 0
mutating func reset(){
self = LevelStruct() //self 프로퍼티 변경 가능
}
}
타입 자체에 호출이 가능한 메서드를 뜻함
메서드 앞에 static
키워드를 사용하여 타입 메서드임을 알릴 수 있음
클래스의 타입 메서드는 static
키워드와 class
키워드를 사용할 수 있음
타입 메서드의 self 프로퍼티는 타입 그 자체를 가리킴
타입 프로퍼티를 제어하기 위해 사용할 수 있음