안녕하세요! 피피아노입니다🎵
이번 포스팅에서는 지난번 포스팅들에 이어서 초기화(Initializers)에 대해서 알아볼 예정인데 이번에는 '2단계 초기화(two-phase initialization)' 라는 것에 대해 한 번 살펴보려고 합니다.
그럼 바로 시작하겠습니다!
2단계 초기화
Swift의 클래스 초기화는 2단계 초기화(two-phase initialization)를 사용합니다.
먼저 1단계 초기화는 클래스에 정의한 각각의 저장 프로퍼티에 초깃값을 할당합니다. 이 단계에서는 모든 저장 프로퍼티에 초기값이 할당되어야 합니다. 그 이유는 모든 프로퍼티가 유효한 상태로 인스턴스가 생성될 수 있도록 보장하기 위해서 입니다.
class Human {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
이 소스에서 볼 수 있듯이, init 메서드 내에서 모든 프로퍼티에 초기값을 할당하고 있습니다.
모든 저장 프로퍼티의 초기 상태가 결정되면 2단계로 돌입해 저장 프로퍼티들을 사용자 정의할 기회를 얻습니다. 그 후 새로운 인스턴스를 사용할 준비가 끝나게 됩니다.
2단계 초기화는 프로퍼티를 초기화하기 전에 프로퍼티 값에 접근하는 것을 막아 초기화를 안전하게 할 수 있도록 해줍니다. 또한, 다른 이니셜라이저가 프로퍼티의 값을 실수로 변경하는 것을 방지할 수도 있습니다.
2단계 초기화는 인스턴스 메서드, 게터, 세터 등을 통해 추가적인 사용자 정의 설정을 수행합니다. 이 단계에서는 인스턴스가 완전히 생성된 후, 추가적인 사용자 정의 설정을 수행할 수 있습니다. 이는 인스턴스가 완전히 초기화된 상태에서만 가능하다는 특징이 있습니다.
class SuperHuman: Human {
var power: String
init(name: String, age: Int, power: String) {
self.power = power
super.init(name: name, age: age)
}
}
위의 예시에서는 SuperHuman 클래스가 Human 클래스를 상속받고 있으며, 1단계에서는 자신의 프로퍼티인 'power'에 초기값을 할당하고, 2단계에서는 'super.init'를 통해 부모 클래스의 초기화를 완료합니다.
이렇게 2단계 초기화를 통해 Swift는 초기화 과정에서의 안전성을 보장하고, 사용자 정의 설정에 대한 유연성을 제공합니다. 이를 통해 인스턴스는 항상 올바른 초기 상태로 생성될 수 있습니다.
4가지 안전확인(Safty-checks)
스위프트 컴파일러는 2단계 초기화를 오류 없이 처리하기 위해서 4가지 안전확인(Safty-checks)을 실행합니다.
- 자식클래스의 지정 이니셜라이저가 부모클래스의 이니셜라이저를 호출하기 전에 자신의 프로퍼티를 모두 초기화했는지 확인합니다.
- 자식클래스의 지정 이니셜라이저는 상속받은 프로퍼티에 값을 할당하기 전에 반드시 부모클래스의 이니셜라이저를 호출해야 합니다.
- 편의 이니셜라이저는 자신의 클래스에 정의한 프로퍼티를 포함하여 그 어떤 프로퍼티라도 값을 할당하기 전에 다른 이니셜라이저를 호출해야 합니다.
- 초기화 1단계를 마치기 전까지는 이니셜라이저는 인스턴스 메서드를 호출할 수 없습니다. 또, 인스턴스 프로퍼티의 값을 읽어들일 수도 없습니다. self 프로퍼티를 자신의 인스턴스를 나타내는 값으로 활용할 수도 없습니다.
클래스의 인스턴스는 초기화 1단계를 마쳤을 때 유효한 인스턴스가 되게 됩니다.
1단계를 아직 마치지 않았다? 그럼 유효하지 않게 됩니다. 프로퍼티는 읽기만 가능하고, 메서드는 호출될 수만 있습니다.
자, 이제 4가지 안전확인에 근거하여 어떻게 2단계 초기화가 이루어지는지 한 번 살펴보겠습니다.
1단계
- 최상위 클래스인 경우, 해당 클래스의 저장 속성을 설정합니다. 만약 서브클래스라면, 슈퍼클래스의 초기화를 먼저 수행한 후, 자체 속성을 초기화합니다.
- 이후, 새로운 인스턴스에 대한 메모리가 확보됩니다. 이 시점에서 메모리는 아직 초기화되지 않은 상태입니다. 이 때문에, 속성 접근이나 메서드 호출은 제한됩니다.
- 지정된 초기화 메서드가 클래스 내의 모든 저장 프로퍼티에 값이 할당되었는지 검사합니다. 이 단계가 완료되면, 해당 클래스의 저장 프로퍼티에 대한 메모리는 초기화된 상태가 됩니다.
- 지정 초기화 메서드는 초기화 과정을 부모 클래스의 초기화 메서드에게 위임합니다.
- 이 과정은 부모 클래스가 상속 체인을 따라 최상위 클래스에 도달할 때까지 반복됩니다.
2단계
- 최상위 클래스에서 최하위 클래스로 이어지는 상속 체인을 따라, 지정 초기화 메서드들이 각각의 인스턴스를 사용자 정의 방식으로 설정합니다. 이 과정에서 self를 이용해 프로퍼티 값을 변경하고, 인스턴스 메서드를 호출하는 등의 작업을 수행할 수 있습니다.
- 최종적으로 각각의 편의 초기화 메서드를 통해 self를 이용한 사용자 정의 작업을 추가적으로 진행할 수 있습니다.
감사합니다.
잘못된 내용이 있거나 더 좋은 내용 피드백은 언제나 환영합니다!
궁금하신 부분은 댓글로 질문 부탁드립니다!
'Apple > Swift' 카테고리의 다른 글
[Swift] 초기화(Initializers) 알아보기 (5) - 요구 이니셜라이저 (0) | 2024.02.16 |
---|---|
[Swift] 초기화(Initializers) 알아보기 (4) - 이니셜라이저의 상속 재정의와 자동 상속 (10) | 2024.02.13 |
[Swift] 초기화(Initializers) 알아보기 (2) - 구조체, Memberwise, 클래스의 초기화, 지정/편의 초기화 (0) | 2024.02.04 |
[Swift] 초기화(Initializers) 알아보기 (1) - 초기화의 개념과 사용 방법, 규칙 (0) | 2024.01.29 |
[Swift] Combine의 Operator 알아보기 (0) | 2024.01.28 |