나의 기록, 현진록

[Swift] 11.1 인스턴스 생성 / 이니셜라이저 / 옵셔널 프로퍼티 / 상수 프로퍼티 본문

Programming/Swift

[Swift] 11.1 인스턴스 생성 / 이니셜라이저 / 옵셔널 프로퍼티 / 상수 프로퍼티

guswlsdk 2021. 7. 23. 11:59
반응형

구조체와 클래스를 생성할 때는 지금까지 기본 이니셜라이저를 사용해 인스턴스를 생성했다면. 초기화는 클래스나 구조체 또는 열거형의 인스턴스를 사용하기 위한 준비 과정입니다. 초기화가 완료된 인스턴스는 사용 후 소멸 시점이 오면 소멸합니다.

 

11.1 인스턴스 생성

초기화 과정은 새로운 인스턴스를 사용할 준비를 하기 위하여 저장 프로퍼티의 초깃값을 설정하는 등의 일을 합니다. ㅇ]이니셜 라이저를 정의하면 초기화 과정을 직접 구현할 수 있습니다. 그렇게 구현된 이니셜라이저는 새로운 인스턴스를 생성할 수 있는 특별한 메서드가 됩니다. 스위프트의 이니셜라이저는 반환 값이 없습니다. 이니셜라이저의 역할은 그저 인스턴스의 첫 사용을 위해 초기화하는 것뿐입니다.

 

이니셜라이저는 해당 타입의 새로운 인스턴스를 생성하기 위해 호출합니다. 이니셜라이저는 func 키워드를 사용하지 않고 오로지 init 키워드를 사용하여 이니셜라이저 메서드임을 표현합니다. init 메서드는 클래스, 구조체, 열거형 등의 구현부 또는 해당 타입의 익스텐션 구현부에 위치합니다. 다만 클래스의 지정 이니셜라이저는 익스텐션에서 구현해줄 수 없습니다.

 

class SomeClass{
    init(){
        //초기화할 때 필요한 코드
    }
}

struct SomeStruct{
    init(){
        //초기화할 때 필요한 코드
    }
}

enum SomeEnum{
    case someCase
    init(){
        //열거형은 초기화할 때 반드시 case중 하나가 되어야 합니다.
        self = .someCase
        //초기화할 때 필요한 코드
    }
}

 

 

11.1.1 프로퍼티 기본값

구조체와 클래스의 인스턴스는 처음 생성할 때 옵셔널 저장 프로퍼티를 제외한 모든 저장 프로퍼티에 적절한 초깃값을 할당해야 합니다. 이니셜라이저가 실행될 때 저장 프로퍼티에 적절한 초깃값을 할당할 수 있습니다. 초기화 후에 값이 확정되지 않은 저장 프로퍼티는 존재할 수 없습니다. 프로퍼티를 정의할 때 프로퍼티 기본값을 할당하면 이니셜라이저에서 따로 초깃값을 할당하지 않더라도 프로퍼티 기본값으로 저장 프로퍼티의 값이 초기화됩니다. 

 

더보기

이니셜라이저를 통해 초깃값을 할당하거나, 프로퍼티 기본값을 통해 처음의 저장 프로퍼티가 초기화될 때는 프로퍼티 감시자 메서드가 호출되지 않습니다.

 struct Area{
     var squareMeter: Double
     init(){
         squareMeter = 0.0 //squareMeter
     }
 }

 let room: Area = Area()

 print(room.squareMeter)

init 이니셜라이저로 인스턴스를 초기화하며 squareMeter의 초깃값은 0.0이 된다.

 

앞서 설명했듯이 이니셜라이저로 저장 프로퍼티에 초깃값을 설정하는 방식도 있지만, 프로퍼티에 기본값을 할당하는 방식을 사용할 수도 있습니다. 

 struct Area{
     var squareMeter: Double = 0.0
 }

 let room: Area = Area()

 print(room.squareMeter)

결과는 같다. 

 

 

 

11.1.2 이니셜라이저 매개변수

함수나 메소드를 정의할 때와 마찬가지로 이니셜라이저도 매개변수를 가질 수 있습니다. 즉, 인스턴스를 초기화하는 과저에 필요한 값을 전달받을 수 있습니다.

 

struct Area{
    var squareMeter: Double
    
    init(fromPy py: Double){
        squareMeter = py * 3.3058
    }

    init(fromSquareMeter squareMeter: Double){
        self.squareMeter = squareMeter
    }
    init(value: Double){
        squareMeter = value
    }
    init(_ value: Double){
        squareMeter = value
    }
}

let roomOne: Area = Area(fromPy: 15.0)
print(roomOne.squareMeter) // 49.587

let roomTwo: Area = Area(fromSquareMeter: 33.06)
print(roomTwo.squareMeter) // 33.06

let roomThree: Area = Area(value: 30.0)
let roomFour: Area = Area(55.0)

//Area() 오류

 

이렇게 사용자 정의 이니셜라이저를 만들면 기존의 기본 이니셜라이저는 별도로 구현해주지 않는 이상 사용할 수 없습니다.

 

 

11.1.13 옵셔널 프로퍼티 타입

초기화 과정에서 값을 초기화하지 않아도 되는, 즉 인스턴스가 사용되는 동안에 값을 꼭 갖지 않아도 되는 저장 프로퍼티가 있다면 해당 프로퍼티를 옵셔널로 선언할 수도 있습니다. 또는 초기화 과정에서 값을 지정해주기 어려운 경우 저장 프로퍼티를 옵셔널로 선안할 수도 있습니다. 옵셔널로 선언한 저장 프로퍼티는 초기화 과정에서 값을 할당해주지 않은다면 자동으로 nil이 할당됩니다.

 

 

class Person{
    var name: String
    var age: Int?

    init(name: String){
        self.name = name
    }
}

let hyunjin: Person = Person(name: "hyunjin")
print(hyunjin.name)
print(hyunjin.age)

hyunjin.age = 1
print(hyunjin.nage)

hyunjin.name = "gg"
print(hyunjin.name)

 

 11.1.14 상수 프로퍼티

이름 프로퍼티를 상수가 아닌 변수로 선언해둔다면 "gg"라는 이름을 할당하고 난 후 전혀 다른 사람으로 변할 수 있습니다. 이런 상황을 방지하려면 name 프로퍼티를 상수로 선언해야 합니다. 이 때 고려해야 할 점이 있습니다. 상수로 선언된 저장 프로퍼티는 인스턴스를 초기화하는 과정에서만 값을 할당할 수 있으며, 처음 할당된 이후로는 값을 변경할 수 없습니다. 

 

class Person{
    let name: String
    var age: Int?

    init(name: String){
        self.name = name
    }
}

let hyunjin: Person = Person(name: "hyunjin")
print(hyunjin.name)

//오류 발생
//hyunjin.name = "gg"
반응형