iOS 🍎/Swift

Swift13 - Initialization & Deinitialization

yongmin.Lee 2021. 2. 2. 18:18

Initialization

Initialization is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and performing any other setup or initialization that is required before the new instance is ready for use.

Setting Initial Values for Stored Properties

Classes and structures must set all of their stored properties to an appropriate initial value by the time an instance of that class or structure is created. Stored properties cannot be left in an indeterminate state.

You can set an initial value for a stored property within an initializer, or by assigning a default property value as part of the property’s definition. These actions are described in the following sections.

 

 

ν”„λ‘œνΌν‹° μ΄ˆκΈ°κ°’

- μŠ€μœ„ν”„νŠΈμ˜ λͺ¨λ“  μΈμŠ€ν„΄μŠ€λŠ” μ΄ˆκΈ°ν™”μ™€ λ™μ‹œμ— λͺ¨λ“  ν”„λ‘œνΌν‹°μ— μœ νš¨ν•œ 값이 ν• λ‹Ήλ˜μ–΄ μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

- ν”„λ‘œνΌν‹°μ— 미리 기본값을 할당해두면 μΈμŠ€ν„΄μŠ€κ°€ 생성됨과 λ™μ‹œμ— μ΄ˆκΈ°κ°’μ„ μ§€λ‹ˆκ²Œ λ©λ‹ˆλ‹€.

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"

 

μ΄λ‹ˆμ…œλΌμ΄μ €(initializer)

- ν”„λ‘œνΌν‹° μ΄ˆκΈ°κ°’μ„ μ§€μ •ν•˜κΈ° μ–΄λ €μš΄ κ²½μš°μ—λŠ” μ΄λ‹ˆμ…œλΌμ΄μ € 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 hana: PersonB = PersonB(name: "hana", age: 20, nickName: "ν•˜λ‚˜")

 

- ν”„λ‘œνΌν‹°μ˜ μ΄ˆκΈ°κ°’μ΄ κΌ­ ν•„μš” 없을 λ•ŒλŠ” μ˜΅μ…”λ„μ„ μ‚¬μš©

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
    }

// μœ„μ™€ λ™μΌν•œ κΈ°λŠ₯ μˆ˜ν–‰
// 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 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() // 주인이 μ—†λŠ” μƒνƒœλΌ 였λ₯˜ λ°œμƒ!!

 

μ‹€νŒ¨κ°€λŠ₯ν•œ μ΄λ‹ˆμ…œλΌμ΄μ €

- μ΄λ‹ˆμ…œλΌμ΄μ € λ§€κ°œλ³€μˆ˜λ‘œ μ „λ‹¬λ˜λŠ” μ΄ˆκΈ°κ°’μ΄ 잘λͺ»λœ 경우 μΈμŠ€ν„΄μŠ€ 생성에 μ‹€νŒ¨ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

- μΈμŠ€ν„΄μŠ€ 생성에 μ‹€νŒ¨ν•˜λ©΄ 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 john: PersonD = PersonD(name: "john", age: 23)
let john: PersonD? = PersonD(name: "john", age: 23)
let joker: PersonD? = PersonD(name: "joker", age: 123)
let batman: PersonD? = PersonD(name: "", age: 10)

print(joker) // nil
print(batman) // nil

 

Deinitialization

A deinitializer is called immediately before a class instance is deallocated. You write deinitializers with the deinit keyword, similar to how initializers are written with the init keyword. Deinitializers are only available on class types.

 

 

λ””μ΄λ‹ˆμ…œλΌμ΄μ €(deinitializer)

- 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 donald: PersonE? = PersonE(name: "donald", child: jenny)
donald?.pet = happy
donald = nil // donald μΈμŠ€ν„΄μŠ€κ°€ 더이상 ν•„μš”μ—†μœΌλ―€λ‘œ λ©”λͺ¨λ¦¬μ—μ„œ ν•΄μ œ, deinit μ‹€ν–‰
// "donaldκ°€ jennyμ—κ²Œ happyλ₯Ό μΈλ„ν•©λ‹ˆλ‹€"