- 타입의 저장 프로퍼티에 대한 초기값을 설정하고, 처음 한 번만 실행되는 설정 수행하기
- 초기화(Initialization)는 클래스, 구조체, 열거형의 인스턴스를 사용하기 위해 준비하는 과정이다.
- 초기자(initializer)를 정의해 초기화 과정을 구현한다.
- 클래스 타입 인스턴스는 소멸자(deinitializer)를 가진다.
저장 프로퍼티에 초기값 설정하기
- 클래스와 구조체는 인스턴스가 생성될 때 모든 저장 프로퍼티에 적절한 초기값이 설정되어 있어야 한다.
- 초기자 또는 기본 정의를 통해 저장 프로퍼티의 초기값을 설정할 수 있다.
- 이 때 설정되는 초기값은 프로퍼티 옵저버를 호출하지 않는다.
struct Fahrenheit {
var temperature: Double
init() {
temperature = 32.0
}
}
var f = Fahrenheit()
print("The default temperature is \(f.temperature)° Fahrenheit")
struct Fahrenheit {
var temperature = 32.0
}
옵셔널 프로퍼티
- 프로퍼티가 옵셔널로 선언되어 있다면, 값을 설정해주지 않아도 초기화 과정에서 자동으로 nil로 설정된다.
class SurveyQuestion {
var text: String
var response: String?
init(text: String) {
self.text = text
}
func ask() {
print(text)
}
}
let cheeseQuestion = SurveyQuestion(text: "Do you like cheese?")
cheeseQuestion.ask()
cheeseQuestion.response = "Yes, I do like cheese."
상수에 값 할당하기
- 초기화 과정 어느 시점에서든 상수에 값을 할당할 수 있다.
- 초기화 과정이 완료되면 상수는 더 이상 변경할 수 없다.
- 클래스 인스턴스의 서브클래스가 원본 클래스 인스턴스의 상수를 초기화 과정에서 변경할 수는 없다.
기본 초기자
- 프로퍼티의 기본값을 모두 제공하는 클래스나 구조체에는 기본 초기자가 제공된다.
class ShoppingListItem {
var name: String?
var quantity = 1
var purchased = false
}
var item = ShoppingListItem()
구조체 - 멤버와이즈 초기자
- 구조체 타입은 아무런 초기자를 정의하지 않으면 멤버와이즈 초기자를 자동적으로 가진다.
- 기본 초기자와는 다르게 기본값이 없는 저장 프로퍼티가 있어도 멤버와이즈 초기자를 가질 수 있다.
- 멤버와이즈 이니셜라이저는 새로운 구조체 인스턴스의 멤버 프로퍼티를 초기화하는 간편한 방법이다.
struct Size {
var width = 0.0, height = 0.0
}
let twoByTwo = Size(width: 2.0, height: 2.0)
- 멤버와이즈 초기자를 호출할 때, 기본값을 가지는 프로퍼티는 값을 생략할 수 있다.
let zeroByTwo = Size(height: 2.0)
print(zeroByTwo.width, zeroByTwo.height)
let zeroByZero = Size()
print(zeroByZero.width, zeroByZero.height)
값 타입을 위한 초기자 위임
- 초기자는 인스턴스의 초기화를 수행하기 위해 다른 초기자를 호출할 수 있다.
- 이것을 초기자 위임(initializer delegation)이라고 하고, 여러 초기자 간의 중복 코드를 방지한다.
- 값 타입은 상속을 지원하지 않기 때문에 초기자 위임 과정이 간단하다.
- 클래스 타입은 다른 클래스로부터의 상속이 가능하기 때문에, 초기화 과정에서 모든 상속받은 저장 프로퍼티에 적절한 값이 들어가게 해야 할 책임이 있다.
- 값 타입에서 커스텀 초기자를 작성할 때, 같은 값 타입인 다른 초기자를 참조하려면 self.init을 사용.
- self.init은 초기자 내부에서만 호출 가능.
struct Size {
var width = 0.0, height = 0.0
}
struct Point {
var x = 0.0, y = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
init() {}
init(origin: Point, size: Size) {
self.origin = origin
self.size = size
}
init(center: Point, size: Size) {
let originX = center.x - (size.width / 2)
let originY = center.y - (size.height / 2)
self.init(origin: Point(x: originX, y: originY), size: size)
}
}
let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
size: Size(width: 3.0, height: 3.0))
- 초기화 과정에서 이미 존재하는 초기자를 사용하면 편리하다.