iOS 기본 (swift)
[iOS - swift] Designated init, Convenience init, 초기화의 핵심, 초기화 상속
jake-kim
2020. 11. 26. 01:08
초기화의 핵심
- 초기화 종류는 2가지 (Designated, convenience)
- 초기화의 목적: 모든 멤버 초기화 (1단계) + 상속받은 멤버들 customizing (2단계)
Designated initializer (지정 초기자)
- 클래스의 모든 프로퍼티를 초기화 해야함
- 클래스 타입은 반드시 한 개 이상의 지정 초기자가 필요
init(parameters) {
statements
}
Convenience initializer (편의 초기자)
- 옵셔널
- Convenience init 내부에서 반드시 Designated Init이 호출되어야 함 (self.init())
convenience init(parameters) {
self.init()
statements
}
초기화 규칙 - 모든 멤버가 초기화 되어야 한다는 보장
- Designated init은 반드시 바로 위 super class의 Designated init을 호출해야함
(delegation: sub class에서 super class의 init호출) - Convenience init은 반드시 같은 클래스의 Designated init을 호출해야함 (Designated init은 모든 멤버 초기화가 보장되므로)
(다른 Convenience를 호출하더라도 최종적으로 Designated init 호출해야함)
2단계 초기화 - 상속에서의 초기화 규칙 (two-phase initialization)
컴파일 강제
첫 단계: 자신의 클래스 멤버 모두 초기화
두 번째 단계: super class로 부터 상속받은 멤버들을 super class의 designated init을 호출함으로서 모두 초기화
- super class의 designated init호출 전에 자신의 멤버 먼저 초기화
- super class로 부터 상속받은 멤버를 초기화 할 때, super class의 Designated init을 먼저 호출
(그렇지 않으면 super class의 Designated init으로 인해 다시 값이 덮어씌워질 위험) - Convenience Init도 마찬가지로 Designatred init호출 후 별도의 값 대입 가능
(위와 같은 이유) - 초기화 중에는 instance method와 instance property사용 불가
2단계 초기화의 원리 이해 - 모든 멤버를 먼저 초기화 하고, 이후 customizing 하는 것
1단계 - 등산 (모든 멤버 초기화)
- 클래스의 init호출
- 클래스 인스턴스에 대한 메모리 할당 (단, 아직 초기화 되지 않음)
- sub class의 멤버들 모두 Designaged로 초기화 (단, 상속받은 멤버들은 아직 초기화x)
- 위에서 Designated init은 super class의 Designated init도 호출 (이 때 상속받은 멤버들 초기화)
- Root class까지 연쇄적으로 진행
- Root까지 가게되면 모든 멤버의 초기화 완료
2단계 - 하강 (상속받은 멤버들에 대한 customizing)
- Root class에서 다시 sub class로 한 단계식 차례대로 하강
- sub class로 내려오면서, super class의 Designated init을 호출한 시점으로 복귀
- 해당 단계에서 상속받은 멤버에 대한 customizing이 가능
- 최 하위 sub class까지 하강
- 모든 클래스의 customizing완료
초기화 자동 상속 - 모든 멤버가 초기화 되어야 하므로, 제약이 따름
- 모든 신규 멤버들에 디폴트 값이 있으면 자동 상속 o
- sub class가 Designated init을 하나도 정의하지 않았으면 자동 상속 o
(Designated init이 하나라도 존재하면 super class의 init 전부 자동 상속 x) - super class의 Designated init을 모두 상속 받거나, 작성하면 Convenience Init은 자동 상속
required init
- required 키워드가 init앞에 붙으면, 모든 sub class들이 명시적으로 해당 초기화를 구현
(required를 붙이면 상속의 의미가 이미 있으므로, override키워드는 붙이지 않음)
참고: docs.swift.org/swift-book/LanguageGuide/Initialization.html