초기화는 사용할 class, struct, enum 의 인스턴스를 준비하는 프로세스다.
초기화에는 해당 인스턴스의 각 Property의 초기값을 설정하거나, 인스턴스를 사용하기 전 필요한 설정, 초기화 를 수행하는 작업을 포함한다.
Objective-C 와 달리 Swift의 초기화는 반환값이 없다.
Objc의 초기화
-(id)init {
self = [super init]
return self
}
Swift의 초기화
init() {
//인스턴스 초기화에 필요한 내용
}
위 코드는 Swift의 가장 단순한 형태의 초기화 코드다. 매개변수가 없는 메서드와 같으며 init키워드를 사용하여 작성한다.
저장속성의 초기값 설정
class / struct는 해당 인스턴스가 생성될 때까지 모든 저장속성에 대해 적절한 초기값을 설정해야한다.
Initializer내에서 저장된 속성의 속성의 초기 값을 설정하거나, 속성 정의의 일부로 기본 속성 값을 할당하여 설정할 수 있다.
저장속성에 기본값을 Init내에서 설정하면 속성관찰자(didSet…)를 호출하지 않고 속성 값이 직접 설정된다.
기본적으로 우리가 사용하는 초기화의 모습이다. 아래 예시를 보자.
struct Person {
var name: String {
didSet {
print("\(name)")
}
}
init(name: String) {
self.name = name
}
}
var json = Person(name: "json")
json.name = "Kavin"
//Print "Kavin"
아래는 Fahrenheit의 저장속성을 초기화하는 init이다.
struct Fahrenheit {
var temperature: Double
init() {
temperature = 32.0
}
}
var f = Fahrenheit()
print("Default temperature is \(f.temperature) Fahrenheit")
//Print "Default temperature is 32.0 Fahrenheit"
위에서 말한것과 같이 init에서 저장속성의 초기화를 담당하도록 한다.
만약 계속 동일한 초기값을 사용하는 경우 Init을 통한 값 설정 보다 아래처럼 기본값을 제공하여 사용하도록하자.
struct Fahrenheit {
var temperature = 32.0
}
이렇게 하면 Init으로 temperature의 초기값을 셋팅해 줄 필요가 없다.
Customizing Initalization
Celsius는 섭씨로 표시된 온도를 저장하는 struct이다.
struct Celsius {
var temperatureInCelsius: Double
init(forFahrenheit fahrenheit: Double) {
temperatureInCelsius = (fahrenheit - 32.0) / 1.8
}
init(fromKelvin kelvin: Double) {
temperatureInCelsius = kelvin - 273.15 //절대 영도
}
//초기화는 반드시 하나일 필요가 없다. 용도에 맞게 초기화를 지원하자.
}
let bolingPointOfWater = Celsius(fromFahrenheit: 212.0)
// boilingPointOfWater.temperatureInCelsius is 100.0
let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// freezingPointOfWater.temperatureInCelsius is 0.0
Celsius는 두개의 사용자 정의 이니셜라이저를 구현, 용도에 맞게 초기화를 Customizing했다.
매개변수 이름 및 인수레이블
초기화 매개변수는 초기화 본체 내에서 사용하기 위한 매개변수 이름과 초기화를 호출할 때 사용하기 위한 인수 레이블을 모두 가질 수 있다.
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)
let veryGreen = Color(0.0, 1.0, 0.0) //! 컴파일 에러 발생!
의도가 명확한 인스턴스는 이름없는 인수레이블을 제공하여 호출할 수 있도록 하는 방법도 있다.
init(_ celsius: Double) {
temperatureInCelsius = celsius
}
let bodyTaemperature = Celsius(37.0)
초기화 시 옵셔널 속성에 대해
nil이 논리적으로 허용되는 저장속성(Optional Property)의 경우 nil로 자동 초기화 되며 “아직 값이 없음”을 의도적으로 표현한다.
class SurveyQuestion {
var text: String
var response: String?
init(text: String) {
self.text = text
//response는 Optional이므로 초기화해주지 않아도 nil로 자동 초기화 된다.
}
}
let cheesQuestion = SurveyQuestion(text: "Do yout like cheese?")
초기화 시 상수 속성에 대해
상수 속성에 값이 할당되면 더 이상 수정할 수 없다.
class SurveyQuestion {
let text: String
var response: String?
init(text: String) {
self.text = text //상수 초기화
}
func ask() {
print(text)
}
}
var beetsQuestion = SurveyQuestion(text: "How about beets?")
beetsQuestion.text = "some Question..." //컴파일 에러 발생!
기본 이니셜라이저
Swift는 모든 속성에 대한 기본값을 제공하고 하나 이상의 이니셜라이저 자체를 제공하지 않는 모든 구조체 또는 클래스에 대한 기본 이니셜라이저를 제공한다.
기본 이니셜라이저는 모든 속성이 기본값으로 설정 된 새 인스턴스를 생성한다.
class ShoppingListItem {
var name: String?
var quantity = 1
var purchased = false
}
var item = ShoppingListItem()
ShoppingListItem 클래스는 모든 속성에 기본값이 있는 상태.
모든 속성이 기본값으로 설정된 인스턴스를 만드는 기본 이니셜라이저를 자동으로 얻는다.
name의 경우 optional이므로 기본값 nil이 셋팅된다.
구조체 유형에 대한 멤버별 이니셜라이저
struct는 사용자 정의 이니셜라이저를 정의 하지 않는 경우 속성값을 값는 이니셜라이저를 제공한다.
기본 이니셜라이저와 달리 구조체는 기본값이 없는 속성이 있더라도 멤버별 이니셜라이저를 받는다.
struct Size {
var width = 0.0, height = 0.0
}
let twoByTwo = Size(width: 2.0, height: 2.0)
위 Size는 기본값이 있는 속성을 생략하여 기본 이니셜라이저를 사용해 인스턴스를 생성할수 있고,
변수width, height의 기본값을 셋팅할수 있는 이니셜라이저도 사용할 수 있다.
Size()
Size(widht: 2.0)
Size(height: 2.0)
값 유형에 대한 초기화 위임
이니셜라이저는 다른 이니셜라이저를 호출하여 인스턴스 초기화 일부를 수행할 수 있다.
이를 이니셜라이저 델리게이션(initializer delegation) 이라 하며 , 여러 이니셜라이저에서 코드가 중복되는 것을 방지하는 효과가 있다.
self.init 을 통해 다른 이니셜라이저를 참조하는데 사용하며, self.init 은 이니셜라이저 내에서만 호출할 수 있다.
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)
}
}
초기화도 상속이 가능하다. 다음은 상속 가능한 초기화를 정리해본다.
'난 iOS개발자 > iOS' 카테고리의 다른 글
initialization -3 (0) | 2022.04.29 |
---|---|
initialization-2 (0) | 2022.04.27 |
Method( Instance Method, Type Method) (0) | 2022.03.16 |
백그라운드모드에서 위치정보 가져오기 (BackgroundModes + LocationUpdates) (0) | 2022.03.04 |
Swift의 Property (0) | 2022.03.03 |