반응형
** edwith - Swift 프로그래밍 입문 강의 참고 **
# init / deinit #
인스턴스를 생성하는 이니셜라이저(init)와 클래스의 인스턴스가 소멸될 때 호출되는 디이니셜라이저(deinit)
프로퍼티 초기값
- swift의 모든 인스턴스는 초기화와 동시에 모든 프로퍼티에 유효한 값이 할당되어 있어야 함.
- 프로퍼티에 미리 기본값을 할당해두면 인스턴스가 생성됨과 동시에 초기값을 지니게 됨.
class PersonA {
// 모든 저장 프로퍼티에 기본값 할당
var name: String = "unknown"
var age: Int = 0
var nickName: String = "been"
}
// 인스턴스 생성
let eenii: PersonA = PersonA()
// 기본값이 인스턴스가 지녀야 할 값과 맞지 않다면 생성된 인스턴스의 프로퍼티에 각각 값 할당
eenii.name = "eenii"
eenii.age = 24
eenii.nickName = "e"
# 이니셜라이저(initializer) - init #
프로퍼티 초기값을 지정하기 어려운 경우에는 이니셜라이져 init을 통해 인스턴스가 가져야 할 초기값을 전달할 수 있습니다.
class PersonB {
var name: String
var age: Int
var nickName: String
// 이니셜라이저
init(name: String, age: Int, nickName: String) {
self.name = name
self.age = age
self.nickName = nickName
}
}
let jihye: PersonB = PersonB(name: "jh", age: 24, nickName: "n")
프로퍼티 초기값이 꼭 필요 없을 때는 옵셔널 사용!
class PersonC {
var name: String
var age: Int
var nickName: String?
init(name: String, age: Int, nickName: String) {
self.name = name
self.age = age
self.nickName = nickName
}
// 위 init 과 동일한 기능 - class 내부의 init을 사용할 때는 convenience 키워드 사용
convenience init(name: String, age: Int, nickName: String) {
init(name: name, age: age)
self.nickName = nickName
}
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
let tw: PersonC = PersonC(name: "tw", age: 25)
let sj: PersonC = PersonC(name: "sj", age: 26, nickName: "k")
암시적 추출 옵셔널은 인스턴스 사용에 꼭 필요하지만 초기값을 할당하지 않고자 할 때 사용
class Puppy {
var name: String
var owner: PersonC!
init(name: String) {
self.name = name
}
func goOut() {
print("\(name)가 주인 \(owner.name)과 산책을 합니다.")
}
}
let happy: Puppy = Puppy(name: "happy")
happy.goOut() // 주인이 없는 상태라 오류 발생
happy.owner = tw
happy.goOut() // happy가 주인 tw과 산책을 합니다.
실패 가능한 이니셜라이저
- 이니셜라이저 매개변수로 전달되는 초기값이 잘못된 경우 인스턴스 생성에 실패할 수 있습니다.
- 인스턴스 생성에 실패하면 nil을 반환
- 실패 가능한 이니셜라이저의 반환타입은 옵셔널 타입
- init? 사용
class PersonD {
var name: String
var age: Int
var nickName: String?
init?(name: String, age: Int) {
if (0...120).contains(age) == false {
return nil
}
if name.characters.count == 0 {
return nil
}
self.name = name
self.age = age
}
}
let jh: PersonD = PersonD(name: "jh", age: 25) // 오류 - 옵셔널이 아니라서.
let tw: PersonD? = PersonD(name: "tw", age: 25)
let sj: PersonD? = PersonD(name: "sj", age: 26)
let sl: PersonD? = PersonD(name: "", age: 10)
print(sj) // nil
print(sl) // nil
# 디이니셜라이저(deinitializer) - deinit #
- deinit은 클래스의 인스턴스가 메모리에서 해제되는 시점에 호출
- 인스턴스가 해제되는 시점에 해야할 일을 구현 가능
- deinit은 매개변수를 지닐 수 없음
- 자동으로 호출되므로 직접 호출 불가능
- 디이니셜라이저는 클래스 타입에만 구현 가능
- 인스턴스가 메모리에서 해제되는 시점은 ARC(Automatic Reference Counting) 문서의 규칙에 따라 결정
class PersonE {
var name: String
var pet: Puppy?
var child: PersonC
init(name: String, child: PersonC) {
self.name = name
self.child = child
}
// 인스턴스가 메모리에서 해제되는 시점에 자동 호출
deinit {
if let petName = pet?.name {
print("\(name)가 \(child.name)에게 \(petName)를 인도합니다.")
self.pet?.owner = child
}
}
}
var hb: PersonE? = PersonE(name: "hb", child: jh)
hb?.pet = happy
hb = nil // hb 인스턴스가 더이상 필요 없으므로 메모리에서 해제
// hb가 jh에게 happy를 인도합니다.
반응형
'iOS > Swift' 카테고리의 다른 글
Swift-8. assert, precondition, guard (0) | 2023.02.24 |
---|---|
Swift-6. 옵셔널 체이닝, nil 병합 (0) | 2023.02.24 |
Swift-4. 클로저, 프로퍼티 (0) | 2023.02.24 |
Swift-3. 구조체, 열거형 (0) | 2023.02.24 |
Swift-2. 반복문, 옵셔널/옵셔널체이닝/옵셔널바인딩 (0) | 2023.02.24 |
댓글