블로그

[Swift] 클래스 초기화 안전검사

게시 4분

class Human { var name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age } }
class Student: Human { var school: String init(name: String, age: Int, school: String) { self.school = school super.init(name: name, age: age) } }
class UnivStudent: Student { var major: String init(name: String, age: Int, school: String, major: String) { self.major = major super.init(name: name, age: age, school: school) } convenience init(age: Int) { self.init(name: "unknown", age: age, school: "Stanford", major: "computer") } }

상속 체인

상속 체인

컴파일러가 클래스의 초기화 과정 이전에 필요한
안전검사에 대해 알아본다.

안전확인

컴파일러가 수행하는 과정이다.
4개의 검사를 수행한다.
① 부모 클래스의 init 실행 전 현재 클래스의 모든 프로퍼티가 초기화 되어야한다.

init(name: String, age: Int, school: String, major: String) { self.major = major super.init(name: name, age: age, school: school) }

UnivStudent의 클래스에서 현재 클래스의 프로퍼티는 major다.
self.major = major 을 통해 UnivStudent의 모든 프로퍼티가 초기화 되었는지 확인한다.
부모 클래스에서 자식 클래스에게만 있는 프로퍼티를 초기화할 수 없으므로 검사를 수행한다.

② 부모에게 상속받은 프로퍼티는 부모 이니셜라이즈가 끝난 후 할당해야한다.

init(name: String, age: Int, school: String, major: String) { self.major = major self.age = 14 // ERROR! super.init(name: name, age: age, school: school) }

self.age는 Human 클래스에게 상속받은 프로퍼티다.
하지만 이 값을 부모의 이니셜라이저 호출 전에 초기화하려 했으므로 에러가 발생한다.

③ ②번과 마찬가지로 편의 이니셜라이저에서도 지정 이니셜라이저 호출 후에 프로퍼티를 초기화해야한다.

convenience init(age: Int) { self.age = 14 // ERROR self.init(name: "unknown", age: age, school: "Stanford", major: "computer") }

④ 초기화 1단계를 마치기 전에는, 인스턴스 프로퍼티/메소드의 프로퍼티를 호출할 수 없고
self 프로퍼티를 참조할 수 없다.

class UnivStudent: Student { var major: String var me: UnivStudent = self // ERROR! var me: UnivStudent = { self }() // ERROR! var me: UnivStudent { self } // Okay init(name: String, age: Int, school: String, major: String) { self.major = major me = self // ERROR! super.init(name: name, age: age, school: school) } convenience init(age: Int) { self.init(name: "unknown", age: age, school: "Stanford", major: "computer") } }

1단계 초기화가 완료되지 않은 상태에서 저장 프로퍼티가 self를 참조할 수 없다.
하지만 연산 프로퍼티는 self를 참조하지 않고, 단순히 값을 반환해주기 때문에 가능하다.

댓글

댓글을 남기면 닉네임(또는 GitHub 계정 정보)이 저장됩니다. 개인정보처리방침

GitHub