본문 바로가기

프로그래밍 [KOR]/Swift

Swift의 인스턴스의 생성과 소멸

•프로퍼티 초기값

•이니셜라이저 init - 인스턴스를 생성

•디이니셜라이저 deinit - 클래스의 인스턴스가 소멸될 때 호출됨



1. 프로퍼티 초기값


  •스위프트의 모든 인스턴스는 초기화와 동시에 모든 프로퍼티에 유효한 값이 할당되어 있어야 함

  •프로퍼티에 미리 기본값을 할당해두면 인스턴스가 생성됨과 동시에 초기값을 지니게 됨


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class PersonA {
    // 모든 저장 프로퍼티에 기본값 할당
    var name: String = "unknown"
    var age: Int = 0
    var nickName: String = "nick"
}
 
// 인스턴스 생성
let jennie: PersonA = PersonA()
 
// 기본값이 인스턴스가 지녀야 할 값과 맞지 않다면
// 생성된 인스턴스의 프로퍼티에 각각 값 할당
jennie.name = "jennie"
jennie.age = 30
jennie.nickName = "j"
cs



2-1. 이니셜라이저(initializer)


  •프로퍼티 초기값을 지정하기 어려운 경우에는 이니셜라이저 init을 통해 인스턴스가 가져야 할 초기값을 전달할 수 있음


1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 jennie: PersonB = PersonB(name: "jennie", age: 20, nickName: "제니")
cs



프로퍼티의 초기값이 꼭 필요 없을 때


  •옵셔널을 사용

  •class 내부의 init을 사용할때는 convenience 키워드 사용


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class PersonC {
    var name: Strong
    var age: Int
    var nickName: String?
 
    init(name: String, age: Int, nickName: String) {
        self.name = name
        self.age = age
        self.nickName = nickName
    }
 
// 위와 동일한 기능 수행
//    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 jennie: PersonC = PersonC(name: "jennie", age: 10)
let lisa: PersonC = PersonC(name: "lisa", age: 15, nickName: "l")
cs



  •암시적 추출 옵셔널은 인스턴스 사용에 꼭 필요하지만 초기값을 할당하지 않고자 할 때 사용


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 = jennie
happy.goOut()
// happy가 주인 jennie와 산책을 합니다
cs



2-2. 실패가능한 이니셜라이저


  •이니셜라이저가 매개변수로 전달되는 초기값이 잘못된 경우 인스턴스 생성에 실패할 수 있음

  •인스턴스 생성에 실패하면 nil을 반환

  •실패가능한 이니셜라이저의 반환타입은 옵셔널 타입

  •init? 을 사용


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 jennie: PersonD = PersonD(name: "jennie", age: 23)
let jennie: PersonD? = PersonD(name: "jennie", age: 23)
let rose: PersonD? = PersonD(name: "rose", age: 123)
let jisoo: PersonD? = PersonD(name: "", age: 10)
 
print (rose) // nil
print (jisoo) // nil
cs



3. 디이니셜라이저(deinitializer)


  •deinit은 클래스의 인스턴스가 메모리에서 해제되는 시점에 호출됨

  •인스턴스가 해제되는 시점에 해야할 일을 구현할 수 있음

  •deinit은 매개변수를 지닐 수 없음

  •자동으로 호출되므로 직접 호출할 수 없음

  •디이니셜라이저는 클래스 타입에만 구현할 수 있음

  •인스턴스가 메모리에서 해제되는 시점은 ARC(Automatic Reference Counting) 의 규칙에 따라 결정됨

  •ARC에 대해 더 자세한 사항은 아래 ARC 문서를 참고


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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 donald: PersonE? = PersonE(name: "donald", child: jennie)
donald?.pet = happy
donald = nil // donald 인스턴스가 더이상 필요없으므로 메모리에서 해제됨
// donald가 jennie에게 happy를 
cs







제 나름대로 생각을 정리하며 포스팅합니다.

정보전달에 있어 차질이 생기는 것을 우려해 나름대로 확실하게 검증을 하고 포스팅하려고 노력합니다.

본 포스팅에 잘못된 정보가 있거나 수정해야할 내용이 있다면 댓글 또는 아래의 이메일로 알려주시면 감사하겠습니다.

E-mail : silent_lhr@naver.com



공감은 로그인이 필요없습니다.

공감은 저에게 포스팅을 이어나갈 수 있는 힘이 됩니다.


'프로그래밍 [KOR] > Swift' 카테고리의 다른 글

Swift의 타입 캐스팅  (0) 2018.10.17
Swift의 옵셔널 체이닝과 nil 병합 연산자  (0) 2018.10.17
Swift의 상속  (0) 2018.10.11
Swift의 프로퍼티 감시자  (0) 2018.10.11
Swift의 프로퍼티  (0) 2018.10.11