스위프트의 모든 인스턴스는 초기화와 동시에 모든 프로퍼티에 유효한 값이 할당되어 있어야 한다.
따라서 저장 프로퍼티를 정의할때는 무조건 기본값을 할당해주어야 한다.
- 기본값 할당된 인스턴스 생성 이후, 프로퍼티 값 할당해주는 경우
class PersonA {
// 모든 저장 프로퍼티에 기본값 할당
var name: String = "unknown"
var age: Int = 0
var nickName: String = "nick"
}
let jason: PersonA = PersonA()
jason.name = "jason"
jason.age = 30
jason.nickName = "j"
하지만 위와 같이 기본값이 정해져있으면, 무조건 기본값으로 기본값 초기화를 한 번 거친 다음 프로퍼티를 할당해주어야 하는 번거로움이 있다.
이런 경우 초기화와 동시에 프로퍼티의 값을 할당해주고 싶다면 이니셜라이저를 사용할 수 있다.
[ 이니셜라이저 ]
이니셜라이저를 사용하면 기본값을 미리 정의해놓을 필요 없이 인스턴스 초기화 과정에서 바로 프로퍼티 값을 할당해 줄 수 있다.
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 hana: PersonB = PersonB(name: "hana", age: 20, nickName: "하나")
프로퍼티의 초기값이 꼭 필요하지 않을 경우에는 옵셔널을 사용해준다.
그리고 경우에 맞게 여러 개의 이니셜라이저를 정의할 수 있고, 내부에서 다른 이니셜라이저를 불러와서 가독성 있게 사용 가능하다.
class PersonC {
var name: String
var age: Int
var nickName: String? // 옵셔널 (초기값이 필요하지 않은 값)
// 경우에 맞게 이니셜라이저를 여러개 만들어 줄 수 있다.
init(name: String, age: Int) {
self.name = name
self.age = age
}
// convenience 키워드를 넣어주면서 다른 이니셜라이저를 내부에서 사용할 수 있다.
convenience init(name: String, age: Int, nickName: String) {
self.init(name: name, age: age)
self.nickName = nickName
}
}
let jenny: PersonC = PersonC(name: "jenny", age: 10)
let mike: PersonC = PersonC(name: "mike", age: 15, nickName: "m")
암시적 추출 옵셔널은 인스턴스 사용에 꼭 필요하지만 초기값을 반드시 할당할 필요는 없을 때 사용 가능하다.
하지만 값이 할당되지 않은 프로퍼티를 사용하려고 할 때는 오류가 발생하므로 사용하기 전에는 값을 할당해 줄 필요가 있다.
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 = jenny
happy.goOut()
// happy가 주인 jenny와 산책을 합니다.

- 실패 가능한 이니셜라이저
이니셜라이저의 매개변수로 전달되는 초기값이 잘못되었을 때는 인스턴스 생성에 실패하면서 nil을 반환하도록 해 줄 수 있다.
실패가능한 이니셜라이저의 반환타입은 옵셔널 타입으로 지정해준다.
class PersonD {
var name: String
var age: Int
var nickName: String?
init?(name: String, age: Int) {
// age가 0~120세가 아니라면 인스턴스 생성 X
if (0...120).contains(age) == false {
return nil
}
// name 글자수가 0자이면 인스턴스 생성 X
if name.count == 0 {
return nil
}
self.name = name
self.age = age
}
}
let john: PersonD? = PersonD(name: "john", age: 23)
let joker: PersonD? = PersonD(name: "joker", age: 123)
let batman: PersonD? = PersonD(name: "", age: 10)
print(john)
print(joker) // nil
print(batman) // nil

[ 디이니셜라이저 ]
deinit은 클래스의 인스턴스가 메모리에서 해제되는 시점에 호출되며, 인스턴스가 해제되는 시점에 해야할 일을 구현할 수 있다.
class PersonE {
var name: String
var pet: Puppy?
var child: PersonC
init(name: String, child: PersonC) {
self.name = name
self.child = child
}
// 디이니셜라이저
deinit {
// personE가 사라지면 personE의 child에게 pet을 인도하면서 pet의 owner가 child로 바뀐다.
if let petName = pet?.name {
print("\(name)가 \(child.name)에게 \(petName)를 인도합니다.")
self.pet?.owner = child
}
}
}
var donald: PersonE? = PersonE(name: "donald", child: jenny)
donald?.pet = happy
donald = nil // donald 인스턴스가 더이상 필요 없으므로 메모리에서 해제된다.
// donald가 jenny에게 happy를 인도합니다.

'Swift' 카테고리의 다른 글
[ Swift ] Swift 기초 문법12 - 타입캐스팅 (0) | 2023.02.19 |
---|---|
[ Swift ] Swift 기초 문법11 - 옵셔널 체이닝과 nil 병합 연산자 (0) | 2023.02.19 |
[ Swift ] Swift 기초 문법9 - 프로퍼티 (0) | 2023.02.17 |
[ Swift ] Swift 기초 문법8 - 클로저 (0) | 2023.01.30 |
[ Swift ] Swift 기초 문법7 - 값 타입과 참조 타입 (클래스, 구조체, 열거형 비교) (0) | 2023.01.30 |
스위프트의 모든 인스턴스는 초기화와 동시에 모든 프로퍼티에 유효한 값이 할당되어 있어야 한다.
따라서 저장 프로퍼티를 정의할때는 무조건 기본값을 할당해주어야 한다.
- 기본값 할당된 인스턴스 생성 이후, 프로퍼티 값 할당해주는 경우
class PersonA {
// 모든 저장 프로퍼티에 기본값 할당
var name: String = "unknown"
var age: Int = 0
var nickName: String = "nick"
}
let jason: PersonA = PersonA()
jason.name = "jason"
jason.age = 30
jason.nickName = "j"
하지만 위와 같이 기본값이 정해져있으면, 무조건 기본값으로 기본값 초기화를 한 번 거친 다음 프로퍼티를 할당해주어야 하는 번거로움이 있다.
이런 경우 초기화와 동시에 프로퍼티의 값을 할당해주고 싶다면 이니셜라이저를 사용할 수 있다.
[ 이니셜라이저 ]
이니셜라이저를 사용하면 기본값을 미리 정의해놓을 필요 없이 인스턴스 초기화 과정에서 바로 프로퍼티 값을 할당해 줄 수 있다.
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 hana: PersonB = PersonB(name: "hana", age: 20, nickName: "하나")
프로퍼티의 초기값이 꼭 필요하지 않을 경우에는 옵셔널을 사용해준다.
그리고 경우에 맞게 여러 개의 이니셜라이저를 정의할 수 있고, 내부에서 다른 이니셜라이저를 불러와서 가독성 있게 사용 가능하다.
class PersonC {
var name: String
var age: Int
var nickName: String? // 옵셔널 (초기값이 필요하지 않은 값)
// 경우에 맞게 이니셜라이저를 여러개 만들어 줄 수 있다.
init(name: String, age: Int) {
self.name = name
self.age = age
}
// convenience 키워드를 넣어주면서 다른 이니셜라이저를 내부에서 사용할 수 있다.
convenience init(name: String, age: Int, nickName: String) {
self.init(name: name, age: age)
self.nickName = nickName
}
}
let jenny: PersonC = PersonC(name: "jenny", age: 10)
let mike: PersonC = PersonC(name: "mike", age: 15, nickName: "m")
암시적 추출 옵셔널은 인스턴스 사용에 꼭 필요하지만 초기값을 반드시 할당할 필요는 없을 때 사용 가능하다.
하지만 값이 할당되지 않은 프로퍼티를 사용하려고 할 때는 오류가 발생하므로 사용하기 전에는 값을 할당해 줄 필요가 있다.
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 = jenny
happy.goOut()
// happy가 주인 jenny와 산책을 합니다.

- 실패 가능한 이니셜라이저
이니셜라이저의 매개변수로 전달되는 초기값이 잘못되었을 때는 인스턴스 생성에 실패하면서 nil을 반환하도록 해 줄 수 있다.
실패가능한 이니셜라이저의 반환타입은 옵셔널 타입으로 지정해준다.
class PersonD {
var name: String
var age: Int
var nickName: String?
init?(name: String, age: Int) {
// age가 0~120세가 아니라면 인스턴스 생성 X
if (0...120).contains(age) == false {
return nil
}
// name 글자수가 0자이면 인스턴스 생성 X
if name.count == 0 {
return nil
}
self.name = name
self.age = age
}
}
let john: PersonD? = PersonD(name: "john", age: 23)
let joker: PersonD? = PersonD(name: "joker", age: 123)
let batman: PersonD? = PersonD(name: "", age: 10)
print(john)
print(joker) // nil
print(batman) // nil

[ 디이니셜라이저 ]
deinit은 클래스의 인스턴스가 메모리에서 해제되는 시점에 호출되며, 인스턴스가 해제되는 시점에 해야할 일을 구현할 수 있다.
class PersonE {
var name: String
var pet: Puppy?
var child: PersonC
init(name: String, child: PersonC) {
self.name = name
self.child = child
}
// 디이니셜라이저
deinit {
// personE가 사라지면 personE의 child에게 pet을 인도하면서 pet의 owner가 child로 바뀐다.
if let petName = pet?.name {
print("\(name)가 \(child.name)에게 \(petName)를 인도합니다.")
self.pet?.owner = child
}
}
}
var donald: PersonE? = PersonE(name: "donald", child: jenny)
donald?.pet = happy
donald = nil // donald 인스턴스가 더이상 필요 없으므로 메모리에서 해제된다.
// donald가 jenny에게 happy를 인도합니다.

'Swift' 카테고리의 다른 글
[ Swift ] Swift 기초 문법12 - 타입캐스팅 (0) | 2023.02.19 |
---|---|
[ Swift ] Swift 기초 문법11 - 옵셔널 체이닝과 nil 병합 연산자 (0) | 2023.02.19 |
[ Swift ] Swift 기초 문법9 - 프로퍼티 (0) | 2023.02.17 |
[ Swift ] Swift 기초 문법8 - 클로저 (0) | 2023.01.30 |
[ Swift ] Swift 기초 문법7 - 값 타입과 참조 타입 (클래스, 구조체, 열거형 비교) (0) | 2023.01.30 |