iOS Swift - Initializer and Deinitializer

longlivedrgn·2022년 9월 2일
0

swift문법

목록 보기
15/36
post-thumbnail

Initializers

  • Initialize는 두 가지의 방법이 있다. 먼저 Default value가 있는 경우, 그리고 없는 경우

  • 1) 선언과 동시에 기본값을 저장한다. 다시 initializer를 사용할 필요가 없음

class Position{
    // 1) 선언과 동시에 기본값을 저장한다. 다시 initializer를 사용할 필요가 없음
    var x = 0.0
}
  • 2) 기본값이 없음 - initializer가 없음 -> initializer를 생성해주어야됨.
class Position{
    // 2) 기본값이 없음 - initializer가 없음 -> initializer를 생성해주어야됨.
    var y: Double
    // optional은 자동으로 nil로 초기화해준다.
    var z: Double?
    
    init() {
        y = 0.0
    }
}
  • init을 여러 개 생성하기 -> convenience init
class SizeObj {
    var width = 0.0
    var height = 0.0
    
    init(width: Double, height: Double) {
        self.width = width
        self.height = height
    }
    
    // init안에 또 init을 넣어보자
    convenience init(value: Double){
        self.init(width: value, height: value)
    }
}

Memberwise Initializer

  • struct에서 알아서 제공해주는 initializer(초기화해주는 함수)이다
struct SizeValue {
    var width = 0.0
    var height = 0.0
}

let s = SizeValue()
// parameter를 통하여 initialize를 한다. -> 즉, initializer가 없으면 default로 제공해준다.
SizeValue(width: 1.2, height: 3.4)

예) default 값이 없을 경우

struct First {
   let a: Int
   let b: Int
   let c: Int
}

let f = First(a: 1, b: 2, c: 3)

예) 부분적으로 default 값이 없을 경우

struct Second {
   let a: Int = 0
   let b: Int = 1
   let c: Int
}
// default 값을 제외하고만 설정하면 된다.
let s = Second(c: 2)

예) let이 아니라 var로 설정이 되어있다면? -> 다 설정할 수 있다.

struct Third {
   var a: Int = 0
   var b: Int = 1
   var c: Int
}

// 모든 값을 다 설정할 수 있다.
let t = Third(a: 1, b: 2, c: 3)

Class Initializer

Designated Initializer

init(parameters) {
	initializeration
}

Convenience Initializer

  • 보조 initializer이다/convenience init은 같은클래스에서 다른 designated 이니셜라이저를 호출해야한다
convenience init(parameters) {
	initialization
}

전체 예)

class Position {
    var x: Double
    var y: Double
    
    // 초기화 값 설정해주기
    init(x: Double, y: Double){
        self.x = x
        self.y = y
    }
    
    // 위의 designated initializer를 실행하기
    convenience init(x: Double){
        self.init(x: x, y: 0.0)
    }
}

Initializer Inheritance

  • super class에 있는 건 superclass가 해결하도록 한다.
class Figure {
   var name: String

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

   func draw() {
      print("draw \(name)")
   }
    
    convenience init() {
        self.init(name: "unknown")
    }
}


class Rectangle: Figure {
    var width: Double = 0.0
    var height: Double = 0.0
    
    init(name: String, width: Double, height: Double){
        // 현재 클래스에 있는 것만 intialize한다.
        self.width = width
        self.height = height
        // super class에 있는 건 superclass가 해결하도록 한다.
        super.init(name: name)
    }

    override init(name: String){
        width = 0
        height = 0
        super.init(name: name)
    }
    
    // 항상 같은 class에 있는 designated initializer만 보조해주므로, override를 하지 않는다.
    convenience init() {
        self.init(name: "unknown")
    }
}

Initializer Delegation

Value Type(Struct)

  • 첫번째 init이 두번째 init을 위임받는다.

struct Size {
   var width: Double
   var height: Double

   init(w: Double, h: Double) {
      width = w
      height = h
   }
   // 앞에 init에게 초기화를 위임한다.
   init(value: Double) {
       self.init(w: value, h: value)
   }
}

Class

  • Convenience Initializer를 사용하자
  • Figure > Rectangle > Square

Figure)

class Figure {
    let name: String
    
    // designated initializer
    init(name: String){
        self.name = name
    }
    
    // convenience initializer
    convenience init() {
        // 앞에서 구현한 designated를 호출한다.
        self.init(name: "unknown")
    }
}

Rectangle)

class Rectangle: Figure {
    var width = 0.0
    var height = 0.0
    
    // delegate up -> superclass의 init을 호출한다.
    init(n: String, w:Double, h: Double) {
        width = w
        height = h
        super.init(name: n)
    }
    
    // 같은 class내의 designated initializer를 호출한다.
    convenience init(value: Double){
        self.init(n:"rect", w: value, h: value)
    }
}

Square)

class Square: Rectangle {
    
    // Rectangle의 Designated initializer를 보조한다.(Designated initializer는 위의 rectangle의 init과 똑같다)
    convenience init(value: Double){
        self.init(n: "square", w: value, h: value)
    }
    
    // 바로 앞의 initializer를 호출하고 있다.
    convenience init() {
        self.init(value: 0.0)
    }
}

Failable Initializer

  • 만약 Initialize를 fail하게 되면 nil을 내뱉게된다.

기본 꼴)

init?(parameters) {
	initialization
}

예)

struct Position {
   let x: Double
   let y: Double
    
    init?(x: Double, y:Double) {
        guard x >= 0.0, y >= 0.0 else{return nil}
        self.x = x
        self.y = y
    }
}
var a = Position(x: 12, y: 34) // 정상 생성

var b = Position(x: -12, y: 0) // nil

Deinitializer

  • parameter와 ReturnType이 없다.
  • 클래스 인스턴스에 nil을 할당하면, deinit 소멸자가 호출이된다.
class Size {
   var width = 0.0
   var height = 0.0
}

class Position {
   var x = 0.0
   var y = 0.0
}

class Rect {
   var origin = Position()
   var size = Size()
    
    // deinit될때 실행이 된다.
    deinit{
        print("deinit \(self)")
    }
}
// nil을 할당할 수 있는 instance 생성
var r: Rect? = Rect()

// 클래스 인스턴스에 nil을 할당하면, deinit 소멸자가 호출이되며 deinit에 구현해 놓은 print()가 호출이된다.
r = nil // deinit __lldb_expr_1.Rect

0개의 댓글