Daily 2019-02-02~03
Daily
-
블로그 이미지 수정하면서 하루를 보냈다.
-
오후 : swift 공부
생성자(initializer, constructor)는 객체를 생성하는 메소드를 지칭합니다. 객체는 일반적으로 클래스를 통해 추상화된 형태로 description이 작성되는데, 이 클래스를 실제로 사용하기 위해서는 실제 메모리에 올라간 객체의 인스턴스를 만들어야 합니다. 이 때, 객체의 인스턴스를 만드는 메소드가 생성자입니다. 다만, Swift에서는 클래스뿐만 아니라, struct에 대해서도 생성자를 지원합니다.
Swift에서 생성자는 init() 형태로 작성되며, 필요하면 argument를 추가해서 작성할 수도 있습니다.
class Car {
let brand: String
init(brand: String) {
self.brand = brand
}
}
생성자 메소드는 작성할 때 몇 가지 조건이 있습니다. 그 조건을 살펴보면 다음 같은 것들이 있습니다.
- 생성자가 메소드가 끝나는 시점에서 객체의 모든 stored properties에는 값이 존재해야 합니다.
- 옵셔널 값은 특별히 값을 지정하지 않아도 nil이 기본으로 들어갑니다.
- property에 default value가 지정되어 있으면 stored property에 특별한 값을 지정하지 않아도 됩니다.
- Constant property(let으로 선언된 property)는 생성자에서만 그 값을 설정할 수 있습니다.
- struct는 생성자를 특별히 작성하지 않아도, memberwise initializer를 제공합니다. 다만, init 메소드를 별도로 작성하게 되면 memberwise initializer는 사용할 수 없게 됩니다.(extension 안에 생성자를 쓰면 memberwise initializer를 그대로 사용할 수 있습니다.)
struct Car {
let brand: String
let price: Int
}
// 별도로 작성하지 않아도 memberwise initializer가 제공됩니다.
let car = Car(brand: "BMW", price: 10000)
Initializer Delegation
Initializer Delegation의 개념은 Initializer가 다른 initializer를 호출하여 인스턴스 생성을 완료하는 것을 의미합니다. Initializer Delegation은 struct와 class인지 여부에 따라 적용되는 부분이 다르고, struct가 class에 비해 상대적으로 더 간단합니다.
Struct
struct가 class에 비해 Initializer Delegation이 간단한 이유는 struct는 상속이 되지 않기 때문입니다. struct는 delegation용으로 self.init() 형태의 initializer만 호출합니다. 아래는 이에 대한 예시입니다.
struct Car {
let brand: String
let price: Int
init() {
// initializer delegation
self.init(brand: "BMW", price: 10000)
}
init(brand: String, price: Int) {
self.brand = brand
self.price = price
}
}
// brand: BMW, price :10000
let car = Car()
앞서서 생성자는 반드시 모든 stored properties들에 대한 값을 설정해주어야 한다고 서술하였습니다. 그런데 위의 예시에서는 init() 메소드는 stored properties의 값을 self.init(brand: "BMW", price: 10000) 호출을 통해 설정합니다. 즉, 이는 초기화의 과정을 자신이 직접하는 것이 아니라, 일부(여기서는 전부) 다른 메소드가 수행하도록 위임한다(delegate)고 할 수 있습니다.
Class
Objective c
- 클래스에서 초기화를 담당하는 메소드는 단 하나이고, 그 메소드를 designated initializer라고 부른다.(다른 초기화 메소드는 designated initializer를 호출해야 한다.)
- Designated initializer는 슈퍼클래스의 designated initializer를 호출해야 한다.
- Designated initializer가 슈퍼 클래스와 다르다면 슈퍼클래스의 designated initializer를 오버라이드하여야 새로운 designated initializer를 호출할 수 있다.
- 초기화 메소드가 여럿이면 헤더에서 designated initializer를 명시하여야 한다.
Swift
- Objc와 다르게 initializer에서 리턴하는 값이 없다.
- Init 호출시에 모든 stored properties에는 적절한 값이 들어가야 하며, 그렇게 설정하고 싶지 않다면 옵셔널로 해당 프로퍼티를 선언해야 한다.
- Constant property는 init 시점에서만 값이 들어갈 수 있다.