Initialization

언제 init 메소드가 필요할까 ??

변수에서는 =하고 값을 넣으면 되니까 그렇게 자주 필요하지는 않다.
또는 늦게 인스턴스화(lazy instantiation)를 해서 처리를 할 수 있다. 프로퍼티는 아마 옵셔널이 될것이다.
인자없는 init으로 쉽게 클래스와 구조체를 생성할 수 있다.

”free” init methods

클래스가 인자없는 init을 자동으로 생성해준다.
구조체는 그 안에 있는 모든 변수들을 초기화 하기위한 자동으로 생성되는 init을 가지고있다.
만약 자신만의 init을 만들었다면 자동으로 생성되는 init은 사용하지 않아야한다.

init 안에서는 뭘 해도 될까 ??

모든 프로퍼티의 값을 설정해 줄 수도 있고, 심지어 이미 기본값을 가진 어떤 프로퍼티를 설정할 수 있다.
심지어 상수 프로퍼티도 설정할 수 있다.(let으로 선언된 변수)
사용자가 만든 init에서 다른 init 메소드들을 부를 수도 있다. (여러 init 메소드에서 다른 init메소드를 한 개만 부를 수 있다.)
부모클래스의 init도 부를 수 있다.

init 안에서 반드시 해주어야 하는 요구사항

init이 끝나는 시점에는 모든 프로퍼티는 반드시 값을 가져야한다. (옵셔널도 값을 가져야한다.)
클래스에는 init 메소드로 두가지 타입이있다. convenience initializers와 designated initializers가 있다. 지정 이니셜라이저는 convenience 단어와 함께 표시되지 않는다. 편의 초기화 함수는 convenience init 무엇무엇~ 이렇게 선언한다.
지정 초기화는 부모클래스에 있는 지정 초기화를 호출해야한다. 그렇게만 할 수 있다. 지정 초기화는 부모 클래스에 있는 편의 초기화를 호출할 수 없다. 또 자신의 클래스에서 부모의 편의 초기화함수를 호출할 수 없다.
클래스에서 사용자가 만든 모든 프로퍼티를 초기화해야한다. 부모 클래스의 init을 부르기 전에.
부모클래스에 있는 어떤 프로퍼티를 건들기 전에 부모클래스의 init을 호출해야한다. (해당클래스에서 일을 하고 -> 부모를 부르고 -> 부모의 프로퍼티에 접근할 수 있다.)
편의 초기화함수는 그 클래스 안에서 편의 init이나 지정 init을 호출하고 초기화해야한다. 부모를 호출할 수는 없다. 편의 초기화 함수는 부모클래스의 초기화함수를 부를 수 없다.
편의 초기화 함수는 어떤 프로퍼티의 값을 설정 할 수 있기전에 반드시 그 init을 호출해야한다. 자신의 클래스나 부모클래스에 있는 것들.
지정 초기화는 자신의 프로퍼티를 먼저 초기화 할 수 있도록 하고, 그럼 그것들이 부모를 부르고 초기화가 된다.

init의 상속

만약 지정 init을 어떤 것도 구현하지 않는다면, 부모클래스의 모든 지정 init을 상속하게된다. 지정 init을 하나라도 구현한다면 부모클래스에 있는 지정 init을 가져오지 않아도 된다.
부모클래스의 모든 지정 init을 override하거나 그것들 중 어느 것도 구현하지 않는다면 부모클래스로부터 모든 편의 초기화함수를 상속 받을 수 있다.
초기화함수를 구현하지 않으면, 부모클래스의 모든 초기화함수를 갖게된다. (편의든 지정이든)

필수 초기화 함수 (Required init)

키워드 required와 함께 init을 표시할 수 있다. (자식클래스는 이 init을 반드시 실행해야한다는 뜻이다.)
위의 규칙을 따른다면 상속할 수도 있다.

실패할 수도 있는 초기화 함수 (Failable init)

옵셔널 값이 반환될 수 있도록한다.
아래의 코드처럼 init뒤에 물음표를 넣어주면된다.

Swift

init?(arg1: Type1, ...) {
    // might return nil in here.
}

객체 만들기 (Creating Objects)

보통은 객체를 만들 때 적절한 인자로 초기화함수를 호출해서 만든다.

Swift

lex x = CalculatorBrain()
lex y = ComlicatedObject(arg1: 42, arg2: "hello", ...)
let z = [String]()

하지만 가끔은 다른 객체들이 객체를 만들어준다.