Initialization

Yuni·2023년 11월 28일

Initialization

: 모든 프로퍼티를 기본값으로 초기화 한다.

(인스턴스 내 기본값이 존재하지 않는 프로퍼티의 경우 → 초기화 실패, 인스턴스 생성불가)

class 와 struct에서의 init

// class의 경우 초기값을 설정해주지 않으면 에러발생

class Person {
    var name: String // 에러발생
    var age: Int // 에러발생
}

struct Person {
    var name: String
    var age: Int
}

designated Inintaializer(지정 생성자)

  • 클래스에 지정된 모든 Property를 반드시 초기화 해야함.
  • 클래스는 반드시 최소 하나 이상의 designated Initializer를 갖고있음
  • 상속받은 클래스가 있는 경우 → 슈퍼 클래스의 init (super.init)을 호출 해야함
class Person {
    var name: String
    var age: Int
    
	// 초기값 설정
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    } 

}

convenience Initializer(편의 생성자)

  • 클래스에 지원되는 보조적인 Initaializer
  • 필요한 경우에만 생성(의무적이지 않음)
  • designated Initalizer 의 파라미터 중 일부를 기본값으로 설정해서 호출할 수 있음
    • → 때문에 designated Initializer 가 반드시 호출되어야 함.
  • 메모리를 찍어내지 않기 때문에 상속이 되지 않는다.
class Student: Person {
    var nickName: String
    
    init(nickNAme: String) {
        self.nickName = nickNAme

			// 상속받은 경우 super.init의 위치는 init의 제일 마지막에 호출.
        super.init(name: "", age: 0) 
    }
    
    convenience init() {
        self.init(nickNAme: "Yuni")
    }
}
class Person {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    convenience init() {
        self.init(name: "w", age: 3)
    }
    deinit{
        print("메모리에서 제거됨")
    }
}
let person = Person(name: "이름", age:0) 

// 지정생성자가 상위라서 convenience에 값이 정의되어 있다고 하더라도
// 지정생성자의 초기화값이 정의되었다면 지정생성자값으로 호출된다.
print(person.name) // '이름'이 출력됨

failable Initaializer(실패 가능한 이니셜라이져) = init?

  • 매개변수로 전달되는 초기값이 잘못된 경우 인스턴스 생성에 실패할 수 있는데
    • 이런 실패할 수 있는 가능성을 내포한 이니셜라이저를 failable Initaializer라고함
    • 실패했을 때 nil 을 반환해주므로 반환 타입이 옵셔널로 지정됨
class Person {
    var name: String
    var age: Int
    
    init?(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

deinitializer = deinit

  • class 인스턴스가 메모리에서 해제될 때 즉시 호출되는 함수 (struct에서는 사용불가)
    • 특정 인스턴스가 더 이상 필요하지 않을 때 메모리 공간 확보를 위해 해당 인스턴스를 자동적으로 메모리 해제시킴(= ARC)
class Person {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    deinit{
        print("메모리에서 제거됨")
    }
}

Q) 프로퍼티 기본값을 활용하는 것과 이니셜라이져를 활용하여 초기값을 주입하는 것은 어떤점에서 다를까?

  • 메모리 관점

    • [할당]
      프로퍼티 기본값 활용은 메모리 할당이 컴파일 타임에서 직접적으로 이루어집니다. 따라서 static dispatch를 통해 메모리 공간 활용에 있어서 (근소한) 이점을 얻을 수 있습니다.
      반면 이니셜라이저 활용은 메모리 할당이 런타임에서 이루어지며 dynamic dispatch가 되어 (근소한) 오버헤드가 발생할 수 있습니다
  • 아키텍처 관점

    • [모듈화]
      initalize를 통해 속성값을 만든다면 모듈화된 객체를 만들 수 있습니다.
      사이즈가 큰 객체가 직접 붙어있기보다는 중간 다리에서 만들 수 있는 계층을 두고 모듈화된 객체들을 서로 연결짓는 것이 객체지향적인 프로그래밍이라고 생각합니다.

    • [재사용성]
      프로퍼티 기본값을 할당할 경우 재사용성 측면에서 유리합니다.
      아래의 예시에서 Car 클래스 객체를 자주 사용할 때 단순히 객체를 만들어주는 것만으로도 속성값이 유지되는 것을 확인할 수 있습니다.

       class Person {
       var name = "yuni"
       var age = 0
       
       ===============================================
       Instance 1       Instance 2       Instance 3
       +-----------+     +-----------+     +-----------+
       |   Person  |     |   Person  |     |   Person  |
       |-----------|     |-----------|     |-----------|
       | color=yuni|     | color=yuni|     | color=yuni|
       |   age=0   |     |   age=0   |     |   age=0   |
       +-----------+     +-----------+     +----------+
       ===============================================

      반면 initialize를 활용할 경우 첫 속성값을 만들때마다 넣어주어야한다는 것과 init 파라미터가 있을 경우 객체 생성마다 파라미터 값을 넣어주어야한다는 약간의 수고로움이 있습니다.

      class Person {
        var name: String
        var age: Int
        
        init(name: String, age: Int) {
            self.name = name
            self.age = age
        }
        
        ===============================================================
        Instance 1             Instance 2             Instance 3
        +--------------+       +--------------+       +--------------+
        |    Person    |       |    Person    |       |    Person    |
        |--------------|       |--------------|       |--------------|
        |  name="zizi" |       |  name="meco" |       |  name="hoho" |
        |    age=10    |       |    age=8     |       |    age=60    |
        +--------------+       +--------------+       +--------------+
        ===============================================================

0개의 댓글