어느덧 SSAC(이제는 SeSAC)
교육과정을 들은지 약 2달의 시간이 흐르고 첫 번째 프로젝트 였던 개인앱 출시 프로젝트가 끝났습니다.
아직 다른분들에게 소개하기 부끄러운 앱이지만 그래도 앱스토어에 제 이름이 적혀있는 앱이 있다는게 뿌듯하네요ㅎㅎ (시간이 걸리더라도 꾸준하게 업데이트 하도록 하겠습니다🔥)
이번 프록젝트를 진행하면서 아직 넘어야 할 산들이 정말 많구나😂 를 많이 느꼈습니다. 오늘부터 다시 교육이 시작됐는데 새로운 마음으로 다시 열심히 해보겠습니다.
클래스나 구조체를 통해서 인스턴스를 생성할 때, 모든 저장 프로퍼티의 값들을 초기화해야 합니다.
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
를 제공하기 때문에 위와 같은 형태로 인스턴스를 생성할 수 있습니다.
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
에 해당합니다.
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() 을 오버로딩 한다고 보는게 맞는것 같습니다..
required initializer
는 자신을 상속하는 서브 클래스들내에서 이니셜라이저를 구현해줘야 된다는것을 알려주기 위해서 사용합니다.
required init?(coder: NSCoder)
override init(frame: CGRect)
이니셜라이저 대충 알고 있으니까 금방 이해하겠지? 빨리 정리하고 오늘 코드로 뷰 짜는거 좀 해봐야지라고 하다가 박살났습니다...
그래도 공식문서와 싸우다 보니 initializer delegation
개념을 어느정도 잡았습니다.
이왕 시작한김에 천천히 문서 다시보고 확실하게 이해해서 다시 정리해보도록 하겠습니다.