Swift: 인스턴스 생성1
이니셜 라이저(initializer)를 정의하면 인스턴스의 초기화 과정을 직접 구현할 수 있다.
구현된 이니셜라이저는 인스턴스를 생성할 수 있는 특별한 메서드가 된다. 반환 값은 없고, 인스턴스를 초기화하는 역할을 한다.
func 키워드를 사용하지 않고, init 키워드만 사용해서 이니셜 라이저 메서드임을 표시할 수 있다.
클래스, 구조체, 열거형등의 구현부 또는 클래스를 제외한 각 타입의 익스텐션 구현부에 위치할 수 있다.
class SomeClass {
init() {
//클래스 이니셜라이저 수행
}
}
struct someStruct {
init() {
//구조체 이니셜라이저 수행
}
}
enum someEnum {
case someCase
init() {
//열거형은 초기화시 반드시 case중 하나가 되어야 한다.
self = .someCase
//열거형 이니셜라이저 수행
}
}
여기서 열거형은 초기화할 때 반드시 case 중 하나가 되어야 한다는 점에 주의하자.
프로퍼티 기본 값 (Default Value)
구조체와 클래스는 생성 시 옵셔널(Optional)저장 프로퍼티를 제외한 모든 저장 프로퍼티에 초깃값(Initial Value)를 할당해야 한다. 옵셔널이 아닌데 값이 확정되지 못한 프로퍼티가 있다면 에러가 발생한다.
저장 프로퍼티 정의 시에 기본 값을 할당하면, 이니셜라이저가 없어도 기본 값으로 프로퍼티의 값이 초기화된다.
이니셜 라이저를 통해서 초깃값을 할당하거나, 기본 값을 통해 저장 프로퍼티가 처음 초기화될 때는 프로퍼티 감시자 메서드가 호출되지 않는다.
struct Area {
var squareMeter: Double
init() {
squareMeter = 0.0
}
}
let room: Area = Area()
print(room.squareMeter) // 0.0
이니셜 라이저 매개변수
이니셜 라이저도 매개변수를 전달받아 인스턴스를 초기화하는 과정에서 필요한 값을 전달받을 수 있다.
struct Area {
var squareMeter: Double
init(fromPy py: Double) {
squareMeter = py * 3.3058
}
init(fromSquareMeter squareMeter: Double) {
self.squareMeter = squareMeter
}
init(value: Double) {
squareMeter = value
}
init(_ value: Double) {
squareMeter = value
}
}
이렇게 사용자 정의 이니셜 라이저를 만들면 기본 이니셜라이저 init()은 따로 구현하지 않으면 사용할 수 없다.
init(fromSquareMeter squareMeter: Double) 이니셜 라이저에서는 self 프로퍼티를 사용하여 이니셜 라이저의 매개변수인 squareMeter와 구분 지었고,
init(_ value: Double)처럼 자동으로 지정되는 전달인자 레이블 이 필요 없다면 와일드카드 식별자(_)를 사용하여 레이블을 없애줄 수 있다.
옵셔널 프로퍼티 타입
프로퍼티를 옵셔널로 선언해서 꼭 값을 가지지 않아도 됨을 표시해 줄 수 있다.
옵셔널로 선어된 경우, 초기화 과정에서 값을 지정해 줄지 않을 경우 nil이 기본값으로 할당된다.
class Person {
var name: String
var age: Int? //옵셔널 선언
init(name: String) {
self.name = name
}
}
let jaehoon: Person = Person(name: "jaehoon")
print(jaehoon.name) //jaehoon
print(jaehoon.age) //nil
초기화 과정에서 age 프로퍼티를 초기화해주지 않아도 문제가 발생하지 않음을 볼 수 있다. 자동으로 nil이 할당되는 것까지 확인할 수 있다.
상수 프로퍼티
변하지 않아야 하는 값이 있을 경우 let 키워드를 사용하여 상수로 선언할 수 있다.
하지만 상수로 선언된 저장 프로퍼티는 인스턴스를 초기화할 때만 값을 할당 할 수 있고, 이후로는 값을 변경할 수 없다.
상수 프로퍼티는 프로퍼티가 정의된 클래스에서만 초기화할 수 있다. 상수 프로퍼티를 가지는 클래스를 할당받은 자식 클래스에서는 상수 프로퍼티의 값을 초기화할 수 없음에 주의하자.
class Person {
let name: String
var age: Int? //옵셔널 선언
init(name: String) {
self.name = name
}
}
let jaehoon: Person = Person(name: "jaehoon")
jaehoon.name = "eunsung" // 에러!