deinit이란?

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


deinit이란?

Deinitialization: 소멸자

소멸자는 클래스 인스턴스가 메모리에서 해제될때 즉시 호출되는 함수이다.
swift의 소멸자는 deinit 키워드를 이용해 사용할 수 있다. 작성방식은 init과 비슷하다!
swift의 소멸자는 구조체가 아닌 클래스 타입에서만 작성이 가능하다.

작동방식

swift는 특정 인스턴스가 더이상 필요없을때 메모리 공간 확보를 위해 해당 인스턴스를 자동적으로 메모리 해제시킨다.
이를 우리가 아는 ARC라고 하고 이 ARC는 전형적으로 특정클래스 인스턴스를 메머리 상에서 해제하고 싶을 때 수동적으로 해당 인스턴스를 정리할 필요가 없게 만든다. 즉 ARC는 더이상 필요없는 인스턴스에 대해서 자동으로 메모리 할당/해제 코드를 실행해준다. 하지만 앱이 자원을 사용하며 작동되고 있을때에는 개인적으로 따로 메모리를 관리해줄 필요가 있다.

클래스의 소멸자는 하나의 클래스 인스턴스 당 최대 하나씩 존재한다. 이러한 소멸자는 별도의 매개변수나 괄호를 명시하지 않는다.

deinit {
  // perform the deinitialization
}

소멸자는 해당 클래스 인스턴스의 메모리 해제가 필요할 때 자동으로 호출된다.
즉, 인스턴스가 메모리 해제되기 직전에 호출된다.

해당 소멸자를 직접 호출하는것은 허용하지 않는다.
상위 클래스의 소멸자는 그들의 서브클래스에 의해 상속된다. 또한 상위 클래스 소멸자는 자동적으로 마지막 서브클래스의 소멸자 구현부에서 호출된다.
상위 클래스의 소멸자는 항상 호출되는데, 아래의 서브클래스 소멸자에서 구현이 없을때에도 호출된다.

소멸자가 호출되기 전까지 인스턴스는 메모리에서 해제되지 않기 때문에 소멸자는 호출되는 인스턴스의 모든 프로퍼티에 접근이 가능하다.
또한 해당 프로퍼티들에 기반한 행위의 변경 또한 가능하다.

class Person {
  var name: String
  var age: Int

  init(name: String, age: Int) {
    self.name = name
    self.age = age
  }

  deinit {
    print("deinit person class instance")
  }
}

// init call
var zehye = Person(name:"zehye", age: 20)

// deinit call
zehye = nil
  • zehye는 Person 클래스의 인스턴스다.
  • 인스턴스 생성 후 해당 인스턴스에 nil을 할당함으로써 메모리를 해제한다.
  • nil을 할당하면 deinit 소멸자가 호출된다.
  • deinitd에 구현해놓은 print()가 호출된다.
  • 콘손에 해당 문구가 출력된다.

그런데 만약 특정 클래스의 인스턴스 사용이 필요없어져 해체를 하고싶은데 deinit이 호출되지 않았다면 이때는 강한참조순환을 의심해보자!
이럴때에는 deinit메서드에 콘솔 출력코드를 두어 메모리 해제여부를 확인해보는것이 방법이다.