NOTE initializer에서 저장 프로퍼티에 값을 직접 설정하면 프로퍼티 옵저버가 호출되지 않고 값 할당이 수행됩니다.
NOTE 항상 같은 초기 값을 갖는 다면 기본 프로퍼티를 사용하는 것이 좋습니다. 프로퍼티에 타입을 선언하지 않아도 컴파일러는 초기 값을 참조해서 타입을 추론할 수 있습니다. 이 기본값은 상속시 함께 상속 됩니다.
let bodyTemperature = Celsius(37.0)
코드와 같이 인자 레이블 없이 Celsius 인스턴스를 초기화 할 수 있습니다.NOTE 클래스 인스턴스에서 상수 프로퍼티는 초기화 중 그 클래스 안에서만 변경이 가능하고 서브클래스에서는 변경이 불가능 합니다.
ShoppingListItem()
를 사용할 수 있음을 보여주는 예제입니다.NOTE 커스텀 이니셜라이저를 사용하면서 기본 이니셜라이저와 맴버쪽 이니셜라이저도 사용하고 싶다면 커스텀 이니셜라이저를 오리지널 클래스에서 구현하지 않고 익스텐션(extension)에서 구현하면 됩니다.
NOTE 이니셜라이저를 익스텐션을 이용해 선언하면 첫번째, 두번째 이니셜라이저는 자동으로 생성되고 익스텐선에 선언한 이니셜라이저도 사용할 수 있습니다.
NOTE 초기자 호출의 모양이 반드시 위 처럼 되야 하는 것은 아닙니다. 다만 위에서 언급만 규칙만 지켜지면 상관 없습니다.
NOTE Swift의 2단계 초기화는 Objective-C에서의 초기화와 유사합니다. 주된 차이점은 첫번째 단계입니다. Objective-C에서는 모든 프로퍼티에 zero 혹은 null 값을 할당합니다. Swift의 초기화는 좀더 유연해서 커스텀한 초기 값을 할 당할 수 있습니다. 그리고 0과 nil이 잘못된 초기값으로 지정된 경우 대처할 수 있습니다.
NOTE Superclass의 이니셜라이저는 안전하고 적당한 특정 환경에서 상속됩니다. 자세한건 아래 내용을 참조하세요.
NOTE subclass의 초기자에서 var은 변경 가능하지만 let은 변경할 수 없습니다.
NOTE 규칙2에따라 서브클래스는 수퍼클래스의 지정초기자를 서브클래스의 편리한 초기자로 구현 가능합니다.
convenience init()
에서 지정초기자 init(name: String)
이 호출되는 형태입니다.init(name: name)
초기자를 상속받아 지정초기자를 생성하고 그 지정초기자를 편리한 초기자 convenience init(name: String)
에서 오버라이딩해 사용합니다. RecipeIngredient에서 초기자가 사용되는 구조를 표현하면 다음 그림과 같습니다.NOTE ShoppingListItem 클래스에서 purchased 프로퍼티 값은 언제나 구매하지 않음(purchased = false)을 시작값으로 사용하기 때문에 이 값을 변경하는 초기자를 제공하지 않습니다. ShoppingListItem 클래스는 새로 생성한 모든 프로퍼티에 대해 기본 값을 제공하고 새로운 초기자를 정의하지 않았기 때문에 자동으로 수퍼클래스의 모든 지정초기자와 편리한 초기자를 상속 받습니다. ShoppingListItem 클래스에서 초기자가 호출되는 구조를 살펴보면 다음과 같습니다.
NOTE 초기자는 이름이 따로 있는 것이 아니라 파라미터로 구분하기 때문에 실패 가능한 초기자와 실패 불가능한 초기자를 같은 파라미터 타입과 이름으로 동시에 사용할 수 없습니다. 실패 가능한 초기자는 반환값으로 옵셔널 값을 생성합니다. 초기화에 실패하는 부분에서 nil을 반환하는 코드를 작성해 초기화가 실패했다는 것을 나타낼 수 있습니다.NOTE 엄밀히 말하면 초기자 init은 값을 반환하지 않습니다. 그래서 비록 nil을 반환하는 return nil 코드에는 사용하지만 init이 성공하는 경우 return 키워드를 사용하지 않습니다. 다음 코드는 숫자형을 위해 정의돼 있는 실패 가능한 초기자 Int(exactly:)를 사용한 예제 입니다.
NOTE 빈것(Empty)과 nil은 다릅니다. 그래서 .isEmpty를 이용해 비교하지 않으면 인스턴스 초기화시“”
를 넣어도 초기화가 됩니다. 이것은 저희가 의도한 동작이 아니니 empty를 확인해서 nil을 반환하도록 구현해야 합니다.
TemperatureUnit(symbol: "F")
에서 F는 TemperatureUnit 열거형에서 사전에 정의돼 있는 단위여서 초기화가 정상적으로 수행됩니다. 반면 TemperatureUnit(symbol: "X")
에서 X는 정의되지 않은 단위여서 초기화에 실패합니다.NOTE 실패가능한 초기자를 실패가 가능하지 않은 초기자에 위임할 수 있습니다. 이런 방식을 조합해 현재 존재하는 초기자를 특정 상황에만 실패하는 초기자로 만들 수 있습니다.
NOTE 실패가능한 초기자를 실패불가능한 초기자에서 오버라이드 할 수 있지만, 그 반대는 불가능합니다.
super.init(name: "[Untitled]")!
NOTE 필수초기자 표시를 해도 꼭 구현을 할 필요는 없습니다.
NOTE 클로저를 초기자에서 사용하면 클로저 안에 self나 다른 프로퍼티를 사용할 수 없습니다. 그 이유는 클로저가 실행될 시점에 다른 프로퍼티는 초기화가 다 끝난 것이 아니기 때문입니다.
Chessboard()
수행으로 8x8 보드 인스턴스가 생성됩니다. 생성된 보드에서 특정 행-열이 어떤 색인지 알아보기 위해 squareIsBlackAt(row: Int, column: Int) 함수를 호출합니다.