-
Swift - Initializer DelegationProgramming/Swift 2021. 11. 28. 19:44
안녕하세요 BeePeach입니다 :)
오늘은 지난 포스팅에 이어서 Initializer의 Delegation에 대해서 공부해보도록 하겠습니다.
이번 장에서는 코드보다 설명이 대부분입니다.
Initializer Delegation이란 initializer에서 다른 initializer를 호출하여 코드의 중복을 최대한 없애는 것을 의미합니다.
Delegation은 Value type과 Reference type에서 구현방식이 조금 다릅니다. 이유는 상속의 유무 때문입니다.
그럼 먼저 Value type의 delegation부터 알아보도록 하겠습니다.
Value Type의 initializer Delegation
Value Type은 상속이 없기 때문에 delegation이 매우 간편합니다.
그냥 initializer를 정의할 때 self.init()을 이용해서 다른 initializer를 호출하면 됩니다.
이렇게 구현한다면 delegation을 이용하지 않은 것입니다.
두 번째 init인 init(value:)를 보면 각각 프로퍼티에 value를 할당하여 초기화하고 있습니다.
하지만 잘 생각해보면 이 코드는 위에 init(x:y:) 코드와 중복이 된다고 볼 수 있습니다.
그렇다면 init(x:y:)를 호출하여 초기화를 delegation(위임) 할 수 있겠죠??
init(value:) 생성자에서 init(x:y:)를 호출했습니다. 그리고 파라미터로 value를 전달했습니다.
이 코드는 위의 코드와 똑같은 기능을 합니다.
아주아주 간단하죠???
하지만 상속이 존재하는 Reference type에서의 Initializer Delegation을 조금 복잡합니다.
그럼 Reference type의 Initializer Delegation을 알아보기 전에 먼저 알고 가야 할 부분부터 짚고 넘어가겠습니다.
Designated Initializer
Designated Initializer(지정 생성자)는 class의 생성자에 기둥과 같은 역할을 하게 됩니다.
Designated Initializer는 class가 가지는 모든 속성을 초기화해야 합니다.
그리고 superclass가 존재한다면 superclass의 initializer를 호출해서 상속 체인 위의 초기화 프로세스가 진행되도록 만들어야 합니다.
이를 Delegate Up이라고 합니다.
마지막 부분이 이해가 잘 안 될 수 있는데 이 부분은 이후에 설명할 class initializer의 초기화를 보고 나면 이해가 조금 더 잘 될 겁니다!
다시 쉽게 말하자면 지정 생성자는 모든 프로퍼티를 초기화시키고 적절한 super.init()을 호출해야 합니다.
모든 class는 적어도 하나 이상의 지정 생성자를 선언해야힙니다.
만약 자동으로 init을 superclass로부터 상속을 받았다면 1개를 선언한 것이 됩니다.
(Init을 상속받는 조건에 대해서는 이후에 자세히 알아보겠습니다)
그리고 일반적으로 지정 생성자는 class당 하나 씩만 선언합니다.
Designated Initializer Syntax
정의하는 방법은 특별한 것이 없습니다.
이전에 선언하던 것처럼 init keyword를 사용하면 됩니다.
Convenience Initializer
Convenience Initializer(간편 생성자)는 보조적인 성격의 생성자입니다.
Convenience Initializer는 필수적인 요소가 아닙니다. 그리고 모든 속성을 초기화하지 않아도 됩니다.
간편하게 필요한 속성만 초기화를 시키고 나머지 초기화는 같은 class의 Designated Initializer를 호출하여 처리합니다.
Convenience Initializer의 조건은 꼭 같은 class의 Designated initializer을 호출해야 합니다. (superclass의 init을 호출할 수 없습니다.)
Designated init을 호출할 때 한 번에 바로 호출해도 되지만 다른 convenience Init을 호출하고 그 convenience init이 designated init을 호출해도 됩니다.
즉 결과적으로 같은 class의 designated init을 호출하기만 하면 됩니다.
Convenience Initializer Syntax
init keyword 앞에 convenience를 추가해주면 됩니다.
아주 간단하죠??
Reference Type Initialzer Delegate의 3가지 규칙
Swift에서 class의 initializer delegation은 3가지 규칙을 따라야 합니다.
1. Designated Initializer는 반드시 superclass의 designated Initalizer를 호출해야 합니다.
2. Convenience Initializer는 반드시 같은 class의 initailizer를 호출해야 합니다.
3. Convenience Initializer는 결과적으로 designated initializer를 호출해야 합니다.
이 3가지 규칙은 위에서 간단하게 설명을 드렸습니다.
1번 규칙을 Delegate up이라고 하며 2, 3번 규칙은 Delegate across라고 합니다.
여기서 주의할 점은 Convenience Initializer는 super.init을 호출할 수 없습니다.
접근 자체가 불가능합니다.
self.init으로 반드시 동일한 class의 init을 호출해야 합니다.
위 그림은 superclass는 1개의 defignated와 2개의 convenience init을 가지는 것을 나타내고 있습니다.
Subclass의 designated init이 superclass의 designated init을 호출하고 있으며 모든 convenience init은 같은 class의 init을 호출하고 결과적으로 마지막에는 degisngated init을 호출하는 것을 확인할 수 있습니다.
이 그림은 조금 더 많은 상속계층을 가진 class의 init구조를 나타낸 그림입니다.
이 그림도 위의 3가지 규칙을 모두 지키고 있습니다.
그리고 designated init의 기둥 역할을 잘 이해할 수 있게 해 줍니다.
이러한 이유는 Swift의 Two-phase Initialization (2단계 초기화)를 공부하고 나면 조금 더 자세히 이해할 수 있습니다.
다음 포스팅에서는 2단계 초기화에 대해서 알아보도록 하겠습니다.
참고 자료
https://docs.swift.org/swift-book/LanguageGuide/Initialization.html
Initialization — The Swift Programming Language (Swift 5.5)
Initialization Initialization is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and performing any other setup or initialization t
docs.swift.org
여러분의 새로운 도전을 응원합니다 | KxCoding
Mastering SwiftUI 더 적은 코드로, 더 멋진 UI 만들기
kxcoding.com
728x90'Programming > Swift' 카테고리의 다른 글
Swift - Initializer - Inheritance, Overriding (0) 2021.12.11 Swift - Initializer - Two Phase Initialization (1) 2021.12.06 Swift - Initializer 기초 (1) 2021.11.13 Swift - Inheritance (상속) (0) 2021.11.11 Swift - Subscript (0) 2021.11.07