๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
iOS ๐ŸŽ/Swift

Swift13 - Initialization & Deinitialization

by yongmin.Lee 2021. 2. 2.

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๋ฅผ ์ธ๋„ํ•ฉ๋‹ˆ๋‹ค"

'iOS ๐ŸŽ > Swift' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Swift15 - Nil-Coalescing Operator  (0) 2021.02.03
Swift14 - Optional Chaining  (0) 2021.02.03
Swift12 - ์ƒ์†  (0) 2021.02.02
Swift11 - ํ”„๋กœํผํ‹ฐ  (0) 2021.02.02
Swift10 - first class citizen  (0) 2021.02.02