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
    }
}

생성자 메소드는 작성할 때 몇 가지 조건이 있습니다. 그 조건을 살펴보면 다음 같은 것들이 있습니다.

  1. 생성자가 메소드가 끝나는 시점에서 객체의 모든 stored properties에는 값이 존재해야 합니다.
    • 옵셔널 값은 특별히 값을 지정하지 않아도 nil이 기본으로 들어갑니다.
    • property에 default value가 지정되어 있으면 stored property에 특별한 값을 지정하지 않아도 됩니다.
  2. Constant property(let으로 선언된 property)는 생성자에서만 그 값을 설정할 수 있습니다.
  3. 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 시점에서만 값이 들어갈 수 있다.
Written on February 2, 2019