Programming/Swift(iOS)

Swift 초기화 메서드

홍열 2021. 4. 2. 21:58
728x90

1. Struct 초기화

- struct는 초기화 메서드가 가지고 있는 프로퍼티에 대해서 자동으로 생성됩니다.

- 따라서 별도로 초기화 메서드를 만들 필요가 없지만, 

- 만약 사용자 초기화 메서드를 작성하는 순간, 시스템에서 제공하는 자동 초기화 메서드는 더 이상 사용할 수 없습니다.

 

- 사용자 초기화 메서드와 시스템 초기화 메서드를 동시에 사용하도 싶다면, "extension"에 사용자 초기화 메서드를 구현하면 됩니다. 

 

//CaseIterable protocol을 만족하므로써 enum이 제공하는 모든 case를 얻어 올 수 있는 
//allCases 메서드 사용가능
enum Color:CaseIterable {
    case red, blue, white, crayon
}

struct Car {
    let name:String
    let color:Color
}

extension Car {
    init(name:String) {
        self.name = name
        //randomElement 자체가 Optional 반환, 아무것도 없을 때 nil을 반환한다.
        self.color = Color.allCases.randomElement()!
        
    }
}
let car:Car = Car(name:"Sonata", color:.red)
let car2:Car = Car(name:"K5")

2. class 초기화

struct와 다르게 class는 초기화 메소드를 반드시 제공해야됩니다.

- 지정 초기화 

일반적으로 사용하는 초기화 방법입니다. 

init함수 호출시 class의 프로퍼티에 대해서 모두 초기화 해주는 것을 말합니다. 

 

car1을 호출할때는 age에 대한 값을 넘겨주지 않았기 때문에 0으로 자동 초기화 됩니다.

class Car {
    let name:String
    var age:Int
    //age가 없으면 0으로 초기화 합니다.
    init(name:String, age:Int = 0) {
        self.name = name
        self.age = age
    }
}

let car1 = Car(name:"K5")
let car2 = Car(name:"K7", age:10)

- require init

: 상속을 받게 되는 클래스에서 반드시 따르도록 강제하는 초기화 메서드입니다.

  자식 클래스에 초기화 메서드가 없으면 상관없지만, 자식클래스에서 따로 초기화 메서드를 구현하는 경우에는 반드시 부모의 require init을 구현해야 합니다.

class Car {
    let name:String
    
    required init(name:String) {
        self.name = name
    }
}

class Truck:Car {
    let weight:Float
    
    init(weight:Float) {
        self.weight = weight
        super.init(name:"Truck")
    }
    
    /* error :
    Insert '
    required init(name: String) {
        fatalError("init(name:) has not been implemented")
    }'
    */
}

 

- convenience 초기화 

기본 init을 도와주는 초기화입니다. 

 

사용자는 age만 입력하면, name은 자동으로 넣어주기를 원합니다.

이럴때 conveience init를 사용해서 age를 먼저 초기화 하고, "super.init(name)"을 호출하여 name을 초기화 하면됩니다.

class Car {
    var name:String = ""
    var age:Int
    init(name:String, age:Int) {
        self.name = name
        self.age = age
    }
    
    convenience init(age:Int) {
        self.init(name:"K3", age:age)
    }
}

let car1 = Car(age:15)

 

- 실패 가능한 초기화

초기화에 전달되는 인자값에 따라서 초기화 하지 못하게 조건을 거는 것입니다. 

return 값으로 nil을 주기때문에 실패 가능하다고 불리는 것입니다.

class Car {
    let name:String
    init?(name:String) {
        if name == "" {
            return nil
        }
        self.name = name
    }
}