Initialization is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and performing any other setup or initialization that’s required before the new instance is ready for use.
초기화 (initialization) 는 사용할 클래스나, 구조체, 또는 열거형 인스턴스를 준비하는 과정입니다. 이 과정은 인스턴스의 각 저장 속성마다 초기 값을 설정하는 것 그리고 새 인스턴스를 사용하기 전에 필수인 다른 어떤 설정이나 초기화를 하는 걸 포함합니다.
하나의 특정한 타입의 새 인스턴스를 생성하고자 호출할 수 잇는 특수한 함수 같은, 이니셜라이저 (initializers) 를 정의함으로써 이 초기화 과정을 구현한다. Objective-C의 이니셜라이저와는 다르게, 스위프트의 이니셜라이저는 값을 반환하지 않는다. 이니셜라이저의 가장 큰 목표는 새 인스턴스가 최초로 사용되기 전에 올바르게 초기화하도록 보장하는 것이다.
클래스 타입 인스턴스는, 그 클래스의 인스턴스 해제 직전에 자신만의 정리를 하는, 디이니셜라이저 (deinitializers) 도 구현 할 수 있다. 디이니셜라이저에 대한 더 많은 정보는 Deinitialization 여기에 있다.
클래스와 구조체는 각자의 인스턴스를 생성하는 시점까지 반드시 (must) 자신의 모든 저장 프로퍼티에 적절한 초기 값을 설정해야 한다. 저장 프로퍼티를 결정하지 않은 상태로 둘 수 없다.
저장 프로퍼티의 초기 값은 이니셜라이저 안에서, 또는 프로퍼티 정의 부분에서 기본 프로퍼티 값을 할당함으로써 설정할 수 있다.
저장 프로퍼티에 기본 값을 할당하거나, 이니셜라이저 안에서 자신의 초기 값을 설정할 땐, 어떤 프로퍼티 관찰자 호출도 없이, 그 프로퍼티 값을 직접 설정합니다.
init
키워드를 써서 작성한다.init() {
// 여기서 블라블라 초기화를 함
}
Fahrenheit
라는 구조체를 정의한다. Fahrenheit
구조체에는 Double
타입인 temperature
라는 저장 프로퍼티가 하나 있다.struct Fahrenheit {
var temperature: Double
init() {
temperature = 32.0
}
}
var f = Fahrenheit()
print("The default temperature is \(f.temperature)° Fahrenheit")
// "The default temperature is 32.0° Fahrenheit" 를 인쇄함
init
이라는 단일 이니셜라이저를 정의하는데, 이는 저장 온도를 (화씨로 물의 어는 점인) 32.0
값으로 초기화한다.프로퍼티가 항상 동일한 초기 값을 취하면, 이니셜라이저 안에서 값을 설정하기 보단 기본 값을 제공하는 것이 좋습니다. 결과는 똑같지만, 기본 값이 프로퍼티 초기화와 그것의 선언을 더 가깝게 묶습니다. 이는 이니셜라이저를 더 짧고, 명확하게 하며 자신의 기본 값으로 프로퍼티의 타입을 추론할 수 있게 합니다. 기본 값은, 기본 초기자 (default initializer) 와 초기자 상속 (initializer inheritance) 이라는 이점도 더 쉽게 취하게 합니다.
temperature
프로퍼티에 기본 값을 제공함으로써 위의 Fahrenheit
구조체를 더 단순한 형식으로 작성할 수 있다.struct Fahrenheit {
var temperature = 32.0
}
(initialization parameters)
를 제공하여, 매개변수의 타입과 이름을 지정하면 초기화 과정을 사용자 정의할 수 있다. 초기화 매개 변수의 보유 능력과 구문은 함수 및 메서드의 매개 변수와 똑같다.struct Celsius {
var temperatureInCelsius: Double
init(fromFahrenheit fahrenheit: Double) {
temperatureInCelsius = (fahrenheit - 32.0) / 1.8
}
init(fromKelvin kelvin: Double) {
temperatureInCelsius = kelvin - 273.15
}
}
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
// boilingPointOfWater.temperatureInCelsius 는 100.0 임
let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// freezingPointOfWater.temperatureInCelsius 는 0.0 임
함수 및 메서드의 매개변수와 같이, 이니셜라이저의 매개변수도 이니셜라이저 본문 안에서 사용할 매개변수 이름과 이니셜라이저를 호출할 때 사용할 아규먼트 레이블 둘 다를 가질 수 있다.
하지만, 이니셜라이저는 함수와 메서드가 가진 괄호 앞 식별 함수 이름을 가지진 않는다. 그러므로, 이니셜라이저의 매개변수의 이름과 타입은 호출해야 할 이니셜라이저를 식별하는 데 특히 더 중요한 역할을 담당한다. 이러한 이유로, 아규먼트 레이블을 제공하지 않으면 스위프트가 이니셜라이저의 모든 매개변수에 자동으로 아규먼트 레이블을 제공한다.
사실, 이니셜라이저는 이름을 가지지 않는다기 보단 모든 함수 이름이
init
으로 똑같은 경우입니다. 그래서, 이니셜라이저를 이름만으로 식별할 순 없습니다. 또한 스위프트가 아규먼트 레이블을 제공한다는 의미는 스위프트가 매개 변수 이름과 똑같은 아규먼트 레이블을 자동으로 만들어 준다는 의미입니다.
struct Color {
let red, green, blue: Double
init(red: Double, green: Double, blue: Double) {
self.red = red
self.green = green
self.blue = blue
}
init(white: Double) {
red = white
green = white
blue = white
}
}
let magenta = Color(red: 1.0, green: 0.0, blue: 1.0)
let halfGray = Color(white: 0.5)
_
) 을 작성하여 기본 동작을 재정의 할 수 있다.struct Celsius {
var temperatureInCelsius: Double
init(fromFahrenheit fahrenheit: Double) {
temperatureInCelsius = (fahrenheit - 32.0) / 1.8
}
init(fromKelvin kelvin: Double) {
temperatureInCelsius = kelvin - 273.15
}
init(_ celsius: Double) {
temperatureInCelsius = celsius
}
}
let bodyTemperature = Celsius(37.0)
// bodyTemperature.temperatureInCelsius 는 37.0 임
Celsius(37.0)
라는 이니셜라이저 호출은 의도가 명확하여 아규먼트 레이블이 필요 없다. 그러므로 이름 없는 Double
값을 제공해서 호출할 수 있도록 이 이니셜라이저를 init(_ celsius: Double)
로 작성하는 게 적절하다.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()
// "Do you like cheese?" 를 인쇄함
cheeseQuestion.response = "Yes, I do like cheese."
response
프로퍼티는 String?
, 또는 “옵셔널 String
” 타입으로 선언한다. SurveyQuestion
의 새 인스턴스를 초기화할 때, “아직 문자열 없음” 을 의미하는 nil
이라는 기본 값을 자동으로 할당한다.클래스 인스턴스에선, (상수 프로퍼티를) 도입한 클래스의 초기화 중에만 상수 프로퍼티를 수정할 수 있습니다. 하위 클래스는 이를 수정할 수 없습니다.
class SurveyQuestion {
let text: String
var response: String?
init(text: String) {
self.text = text
}
func ask() {
print(text)
}
}
let beetsQuestion = SurveyQuestion(text: "How about beets?")
beetsQuestion.ask()
// Prints "How about beets?"
beetsQuestion.response = "I also like beets. (But not with cheese.)"
class ShoppingListItem {
var name: String?
var quantity = 1
var purchased = false
}
var item = ShoppingListItem()
자신만의 이니셜라이저를 어떤 것도 정의하지 않은 구조체 타입은 자동으로 멤버와이즈 이니셜라이저 (memberwise initializer) 를 받는다. 기본 이니셜라이저와 달리, 저장 프로퍼티가 기본 값을 가지지 않은 경우라도 구조체는 멤버와이즈 이니셜라이저를 받는다.
멤버와이즈 이니셜라이저는 새 구조체 인스턴스의 멤버 프로퍼티 초기화를 짧게 줄인 것이다. 이름으로 새 인스턴스 속성의 초기 값을 멤버와이즈 이니셜라이저에 전달할 수 있다.
struct Size {
var width = 0.0, height = 0.0
}
let twoByTwo = Size(width: 2.0, height: 2.0)
Size
구조체는 height
와 width
프로퍼티 모두에 기본 값이 있다. 하나의 프로퍼티 혹은 두 프로퍼티 모두 생략할 수 있으며, 생략한 것은 이니셜라이저가 기본 값을 사용한다. let zeroByTwo = Size(height: 2.0)
print(zeroByTwo.width, zeroByTwo.height)
// Prints "0.0 2.0"
let zeroByZero = Size()
print(zeroByZero.width, zeroByZero.height)
// Prints "0.0 0.0"