Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

욤찌의 개발 일기

[Swift] 나는 그저 Convenience Initializers 가 알고싶었을 뿐인데,,~ 본문

Swift

[Swift] 나는 그저 Convenience Initializers 가 알고싶었을 뿐인데,,~

yyomzzi 2023. 11. 1. 00:10

어제에 이어서 오늘도 계속되는 iOS 면접 질문 타파 !!!!!

나는 그저 initializer 공부를 하려고 했는데,, 하다보니까 상속이랑 재정의도 공부하게 되고,,

그러다 보니까 어쩌다 보니까 class 전체를 공부하게 되었다가 ,, 하루가 다 가부렀다,,~

이러다가는 today에 배운 것을 오늘 안에 못적을 것 같아서,,^^ 황급히 마무리하고

Convenience Initializers 만 간단하게 쭈절쭈절 해보겠다


💡Convenience init에 대해 설명하시오.

1) 일단 그 전에 초기화란 무엇인가! 

구조체, 열거형, 클래스의 인스턴스를 생성하는 것을 초기화라고 함.

초기화에서 가장 중요한 것은! 인스턴스가 초기화될 때, 저장 프로퍼티는 초기값을 반드시 가지고 있어야 함.

Stored properties can’t be left in an indeterminate state.

(저장 프로퍼티를 확정되지 않게 두는 것은 절대 있을 수 없는 일이다,,)

구조체와 클래스의 초기화는 같은듯 아주 약간 다른데 오늘은 일단 편의생성자만 다룰 것이기에 클래스의 초기화만 언급해보겠다.

 

2) 초기화는 어떻게 하는가?

그렇다면 인스턴스가 초기화되는 시점에 저장 프로퍼티에 초기값을 설정해준다면 초기화가 완료될 것이다.

구조체와 클래스의 초기화 방법은 똑같이 3가지 방법이 있다.

1️⃣ 저장 프로퍼티를 정의하면서 동시에 초기값을 저장한다.

class Person {
	var name: String = "욤지"
  	var age: Int = 20
}

저장 프로퍼티를 선언함과 동시에 초기값을 설정해주면서 초기화를 완료한다.

 

2️⃣ 저장 프로퍼티의 타입을 옵셔널로 선언한다. 

class Person {
	var name: String?
  	var age: Int?
}

옵셔널로 선언하게 되면 자동으로 nil을 초기값으로 설정해준다.

단, 옵셔널로 선언하게 될 때는 var로 선언해주어야 한다.

지금 nil이 값으로 할당되었는데 다른 값을 할당하게 되면 ,, 상수로 선언하지 못하니께,,!

 

3️⃣ init 함수를 통해 초기값을 설정해준다.

class Person {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

init 함수를 통해서 초기화가 될 때 함수 파라미터로 직접 값을 입력받아서 초기값을 설정할 수 있게 해준다.

해당 init 함수가 종료되기 전에 초기화가 완료되어야 인스턴스가 생성된다.

단, 위의 1번, 2번 방법으로 모든 저장 프로퍼티의 초기화가 완료되었다면 init 함수를 생성하지 않아도 된다. 

 

 

3) class의 Initializers

위에서 구조체와 클래스의 초기화가 비슷하면서도 다르다고 했던 것 중 하나가 바로 지정 생성자와 편의 생성자의 개념이다.

 

1️⃣ 지정 생성자 (Designated Initializers)

사실 우리가 늘 써오던 init() 이 바로 지정 생성자임! 우리는 기본적으로 지정생성자로 초기화를 해주고 있었음. 

그래서 지정 생성자는 클래스에 main 초기화 구문이라고 본다.

구조체에는 memberwise initializer라는게 존재해서 init()으로 모든 저장 프로퍼티를 다루지 않아도 되지만

클래스에는 이런 기능이 없기 때문에 이 지정 생성자가 모든 프로퍼티를 포함해야 함. 
그래서 저장 프로퍼티를 선언하면서 초기값을 지정하거나 옵셔널로 선언한 경우가 아니라면 

지정 생성자에서 꼭!! 초기화를 해줘야함!

 

2️⃣ 편의 생성자 (Convenience Initializers)

바로 이것을 위해 지금까지 달려왔다,, 편의 생성자,, 

이 편의 생성자는 모든 프로퍼티를 다 포함해야 하는 지정 생성자와는 달리, 편리하게 초기화 하고 싶은 프로퍼티만 담아서

초기화 구문을 만들 수 있도록 하는 것이다. 

편의 생성자 앞에는 convenience 키워드를 붙여준다. 

class Person {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    // 요로케!!
    convenience init() {
        self.init(name: "욤지", age: 20)
    }
}

이름부터 알 수 있듯이 진짜 개발자들 편~하게 쓰라고 만들어준 생성자이다. 그래서 지정 생성자의 보조 역할로 보면 된다.

하지만 아무리 편리해도 결국 보조 역할일 뿐임! 그래서 꼭 self.init을 통해 지정 생성자를 호출해서 사용해야 한다. 

보조이기 때문에 메인 생성자인 지정생성자에게 의존해야하는 형태라고 생각하면 된다.

근데 사실 init() 도 오버로딩이 되기 때문에,, 그냥 여러개의 init()을 만들면 되는거 아닌가? 싶지만

대부분 클래스에서는 지정생성자는 안만들거나 하나만 만들고, 추가로 더 편하게 사용하려면 파라미터 일부만 초기화해서 편의 생성자를 사용하는 것이 가장 바람직하다고 본다. (유지보수가 더 쉽다고 한다.)

 

 

4) 클래스 타입에 대한 초기화 구문 위임 (Initializer Delegation for Class Types)

위에서 클래스를 초기화하는 지정 생성자와 편의 생성자 함수에 대해서 알아보았는데 

Initializer Delegation 이라는 규칙이 존재한다.

 

1️⃣ 지정 생성자의 경우, 반드시슈퍼클래스의 지정 생성자를 호출해야 한다.

기본적으로 상속을 할 경우에 슈퍼클래스의 생성자를 상속받지 않는다.(물론 예외도 있다.) 

그렇기 때문에 만약 슈퍼클래스의 저장 프로퍼티가 초기값이 설정되어 있지 않거나 옵셔널 처리도 되어있지 않다면

초기화가 되어있지 않기 때문에 꼭! 서브클래스의 지정 생성자에서 혹시 모르니까 슈퍼클래스의 지정 생성자를 호출해서

초기화를 해주는 것이다~

 

2️⃣ 편의 생성자는 같은 클래스로부터 다른 초기화 구문을 호출하거나 궁극적으로는 지정 생성자를 호출해야한다.

편의 생성자는 진짜 편~하라고 만들어 준것이다.

하지만 언제만 편할 수 있냐면 바로 지정 생성자가 모든 프로퍼티를 초기화 해줄때!

그래서 해당 편의 생성자가 포함된 클래스에 서로 다른 편의 생성자끼리도 호출 하면서 편하게 사용할 수 있지만 궁극적으로는 모든 프로퍼티를 초기화 해주는 지정 생성자를 보조해서 편리하게 사용할 수 있는 것이기 때문에 지정 생성자를 호출해야한다.

 

 

그래서 공식문서에 있는 애플이 알려주는 쉽게 기억하는 방법 (두구두구)

⭐️ 지정 생성자는 항상 위로 위임해야 합니다.

⭐️ 편의 생성자는 항상 옆으로 위임해야 합니다.

 

아래 그림은 공식문서에서 더 쉬운 설명을 위해 첨부해준 그림입니다.

이해가 쉬워서 가져와봤습니다~~!

** 지정 생성자는 위로~ 편의 생성자는 옆으로~

 

 


항상 블로그 쓰는게 뭔가 힘이 들어서,, TIL 만큼은 간단하게! 진짜 오늘 배운거 간단명료하게! 써야지! 하면서도

자꾸자꾸 욕심이 나서 조금씩 길어지는 기분이다,,~

그래도 이렇게 하나씩 배우고 정리하는게 넘넘넘 재밌다ㅠㅠ 

이렇게 배운걸 잘 적용해야 할텐데,,~~,,~~~~~

내일도 재밌는거 배워서 야무지게 정리해야지

그리고 오늘 다 못쓴거 주말에 꼬옥 정리해야지 ~~!~!~!

잘못된 정보에 대한 댓글은 언 제 나 환 영 입 니 다 ♥️ 함께 공부해요~~!~!

 

 

📖 reference(늘 감사합니당) ♥️

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/initialization#Designated-Initializers-and-Convenience-Initializers

 

Documentation

 

docs.swift.org

https://velog.io/@s_sub/Swift-생성자

 

[Swift] 지정생성자 & 편의생성자

구조체 생성자 / 클래스 생성자 / 지정 생성자 / 편의 생성자 / 생성자 상속 규칙

velog.io

https://babbab2.tistory.com/168

 

Swift) 초기화(Initializers) 이해하기 (2/6) - 클래스의 초기화(Designated / Convenience)

안녕하세요 :) 코들입니다.. 코로나에 걸려 죽다 살아 돌아온 소들이라 볼 수 있습니다 아직도 마지막 잎새마냥 기침하며 포스팅 적는 중.. ...뭐야 위 세 줄 쓴 뒤로 3주지남.. 진짜 죽었었나.. 쨌

babbab2.tistory.com