[iOS] Initializer - 01

Sangwon Shin·2021년 12월 13일
0

iOS

목록 보기
4/9

😿 들어가기전에...

어느덧 SSAC(이제는 SeSAC) 교육과정을 들은지 약 2달의 시간이 흐르고 첫 번째 프로젝트 였던 개인앱 출시 프로젝트가 끝났습니다.

아직 다른분들에게 소개하기 부끄러운 앱이지만 그래도 앱스토어에 제 이름이 적혀있는 앱이 있다는게 뿌듯하네요ㅎㅎ (시간이 걸리더라도 꾸준하게 업데이트 하도록 하겠습니다🔥)

이번 프록젝트를 진행하면서 아직 넘어야 할 산들이 정말 많구나😂 를 많이 느꼈습니다. 오늘부터 다시 교육이 시작됐는데 새로운 마음으로 다시 열심히 해보겠습니다.


🔎 Initializer

클래스나 구조체를 통해서 인스턴스를 생성할 때, 모든 저장 프로퍼티의 값들을 초기화해야 합니다.

1) Default initializer

class User {
    var name: String = ""
    var age: Int = 0
}

struct UserStruct {
    var name: String = ""
    var age: Int = 0
}

let a = User() //Default Initializer
let b = UserStruct() //Default Initializer
let c = UserStruct(name: "sangwon", age: 26) // Memberwise Initalizer

위와같이 객체를 만들 때, 임의의 디폴트 값들로 초기화 해주는 형태를 Default initalizer 라고 합니다.

구조체는 클래스와 달리 Memberwise initalizer 를 제공하기 때문에 위와 같은 형태로 인스턴스를 생성할 수 있습니다.


2) Designated initializer

class Coffee {
    let shot: Int
    let size: String
    let menu: String
    let mind: String
    
    //Designated initializer
    init(shot: Int, size: String, menu: String, mind: String) {
        self.shot = shot
        self.size = size
        self.menu = menu
        self.mind = mind
    }
}

let coffee = Coffee(shot: 2, size: "short", menu: "아아", mind: "고마 최선을 다해서")

우리가 일반적으로 클래스를 만들때 만들었던 이니셜라이저가 Designated initializer 에 해당합니다.


3) Convenience initializer

class Coffee {
    let shot: Int
    let size: String
    let menu: String
    let mind: String
    
    //Designated initializer
    init(shot: Int, size: String, menu: String, mind: String) {
        self.shot = shot
        self.size = size
        self.menu = menu
        self.mind = mind
    }
    
    //기본 형태-> 기존에 이미 생성된 생성자를 이용해서 새로운 생성자를 정의할 수 있다
    convenience init(value: String) {
        self.init(shot: 2, size: "보통", menu: value, mind: "정성을 가득 담아~")
    }
}
let coffee2 = Coffee(value: "뜻뜻한 아아")

클래스에서 사용할 수 있는 보조 이니셜라이저로 기존의 이니셜라이저의 파라미터 중 일부를 기본값으로 설정해서 초기화를 진행할 수 있습니다.


다른 이니셜라이저들을 더 보기 전에, 이니셜라이저를 포함한 클래스를 상속하는 경우에 대해서 먼저 살펴보겠습니다.

class A {
    var value: Int
    init() {
        self.value = 10
    }
}

class B: A {
    var value2: Int
    init(newValue: Int) {
//        super.init()
        self.value2 = newValue
        super.init()
    }
}

let test: B = B(newValue: 20)
print(test.value)
print(test.value2)

위와 같이 슈퍼 클래스 A - 서브 클래스 B 로 구성된 예제가 있습니다.
서브 클래스 B 는 A에는 존재하지 않는 value2 라는 저장 프로퍼티를 가지고 있습니다.

그렇기 때문에 클래스 B 의 이니셜라이저를 보면 value2 를 초기화 해주고 슈퍼 클래스 A의 이니셜라이저를 사용해 value 를 초기화 해주는 것을 확인할 수 있습니다.
❗️이때, super.init()을 먼저 호출하면 오류가 발생합니다.
서브 클래스의 프로퍼티를 먼저 초기화 하고 super.init()을 호출해야 합니다.

이니셜라이저를 상속받는데 왜 override 를 사용하지 않을까요?

Swift 는 클래스를 상속받아도 서브클래스가 슈퍼클래스의 이니셜라이저를 자동으로 상속받지는 않습니다.

처음에는 클래스를 상속받으면 생성자도 함께 상속받아서 사용하면 형태로 이해했는데 일반적인 경우는 init() 을 오버로딩 한다고 보는게 맞는것 같습니다..

4) Required initializer

required initializer 는 자신을 상속하는 서브 클래스들내에서 이니셜라이저를 구현해줘야 된다는것을 알려주기 위해서 사용합니다.


🏷 P.S.

required init?(coder: NSCoder)
override init(frame: CGRect)

이니셜라이저 대충 알고 있으니까 금방 이해하겠지? 빨리 정리하고 오늘 코드로 뷰 짜는거 좀 해봐야지라고 하다가 박살났습니다...

그래도 공식문서와 싸우다 보니 initializer delegation 개념을 어느정도 잡았습니다.

이왕 시작한김에 천천히 문서 다시보고 확실하게 이해해서 다시 정리해보도록 하겠습니다.

참고한 사이트

profile
개발자가 되고싶어요

0개의 댓글