스위프트의 dealloc


145

뷰 컨트롤러의 수명이 끝날 때, 즉 NSNotificationCenter알림 을 제거하기 위해 정리를 수행하고 싶습니다 . 구현 dealloc하면 Swift 컴파일러 오류가 발생합니다.

Cannot override 'dealloc' which has been marked unavailable

Swift에서 개체 수명이 다했을 때 정리를 수행하는 기본 방법은 무엇입니까?

답변:


333
deinit {
    // perform the deinitialization
}

로부터 스위프트 문서 :

초기화 해제는 클래스 인스턴스 할당이 해제되기 직전에 호출됩니다. init 키워드로 intializers를 작성하는 방법과 유사하게 deinit 키워드를 사용하여 deinitializer를 작성합니다. 초기화 해제 기는 클래스 유형에서만 사용할 수 있습니다.

일반적으로 인스턴스 할당이 해제 될 때 수동 정리를 수행 할 필요가 없습니다. 그러나 자체 리소스로 작업하는 경우 추가 정리를 직접 수행해야 할 수도 있습니다. 예를 들어, 파일을 열기 위해 사용자 정의 클래스를 작성하고 일부 데이터를 작성하는 경우 클래스 인스턴스를 할당 해제하기 전에 파일을 닫아야합니다.


45
deinit {
    // perform the deinitialization
}

Swift "dealloc"에 대한 정답입니다.

그러나 NSNotificationCenter를 더 이상 정리할 필요가 없다는 iOS 9의 새로운 점을 지적하는 것이 좋습니다!

https://developer.apple.com/library/content/releasenotes/Foundation/RN-FoundationOlderNotes/index.html#X10_11Notes

NSNotificationCenter

OS X 10.11 및 iOS 9.0에서 NSNotificationCenter 및 NSDistributedNotificationCenter는 더 이상 할당이 취소 될 수있는 등록 된 관찰자에게 알림을 보내지 않습니다. 옵저버를 제로화 약한 참조로 저장할 수있는 경우 기본 저장소는 옵저버를 제로화 약한 참조로 저장하거나 객체를 약하게 저장할 수없는 경우 (즉, 런타임을 방해하는 사용자 지정 유지 / 해제 메커니즘이 있음) 객체를 약하게 저장할 수없는 것) 객체를 약한 영점이 아닌 참조로 저장합니다. 이는 옵저버가 할당 해제 방법으로 등록을 취소 할 필요가 없음을 의미합니다. 해당 관찰자에게 라우팅되는 다음 알림은 제로화 된 참조를 감지하고 관찰자를 자동으로 등록 취소합니다. 객체가 약하게 참조 될 수있는 경우 할당 해제 중에 더 이상 알림이 관찰자에게 전송되지 않습니다. 비할 당하게 0이 아닌 참조 옵저버의 경우, 할당 해제 중 알림 수신의 이전 동작이 여전히 존재합니다. -[NSNotificationCenter addObserverForName : object : queue : usingBlock] 메소드를 통한 블록 기반 옵저버는 시스템이 여전히 이러한 옵저버에 대한 강력한 참조를 보유하므로 더 이상 사용하지 않을 때 등록을 해제해야합니다. 약한 참조 또는 제로 참조를 조기에 제거하는 것은 여전히 ​​지원됩니다. 관찰자가 개체가 아닐 수 있으므로 CFNotificationCenterAddObserver는이 동작을 따르지 않습니다. -[NSNotificationCenter addObserverForName : object : queue : usingBlock] 메소드를 통한 블록 기반 옵저버는 시스템이 여전히 이러한 옵저버에 대한 강력한 참조를 보유하므로 더 이상 사용하지 않을 때 등록을 해제해야합니다. 약한 참조 또는 제로 참조를 조기에 제거하는 것은 여전히 ​​지원됩니다. 관찰자가 개체가 아닐 수 있으므로 CFNotificationCenterAddObserver는이 동작을 따르지 않습니다. -[NSNotificationCenter addObserverForName : object : queue : usingBlock] 메소드를 통한 블록 기반 옵저버는 시스템이 여전히 이러한 옵저버에 대한 강력한 참조를 보유하므로 더 이상 사용하지 않을 때 등록을 해제해야합니다. 약한 참조 또는 제로 참조를 조기에 제거하는 것은 여전히 ​​지원됩니다. 관찰자가 개체가 아닐 수 있으므로 CFNotificationCenterAddObserver는이 동작을 따르지 않습니다.

그러나 강력한 참조에 대해서는 아래 사항을 참고하십시오. 그래도 정리에 대해 걱정해야 할 수도 있습니다 ...?


3
알림 블록에 강력한 참조가 없으면 관찰자를 제거해야합니다.
TigerCoding

관찰자를 정리하지 않아도 +1 알아야 할 중요한 사항! 나는 모든 캡처 참조를 약하게 만들므로 이것을 다루지 않아도됩니다.
n13

2
알림 블록은 항상 설명서에 따라 강력하게 참조되는 것 같습니다. 그래서 : 당신이 당신의 통지를 처리하기 위해 블록을 사용하는 경우, 당신은 deinit 안에 그들을 위해 등록을 취소 할 수 있습니다.
marsbear

22

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Deinitialization.html

Swift는 더 이상 필요하지 않은 인스턴스를 자동으로 할당 해제하여 리소스를 확보합니다. Swift는 자동 참조 계산에 설명 된대로 자동 참조 계산 (ARC)을 통해 인스턴스의 메모리 관리를 처리합니다. 일반적으로 인스턴스 할당이 해제 될 때 수동 정리를 수행 할 필요가 없습니다. 그러나 자체 리소스로 작업하는 경우 추가 정리를 직접 수행해야 할 수도 있습니다. 예를 들어, 파일을 열기 위해 사용자 정의 클래스를 작성하고 일부 데이터를 작성하는 경우 클래스 인스턴스를 할당 해제하기 전에 파일을 닫아야합니다.

클래스 정의는 클래스 당 최대 하나의 초기화 해제기를 가질 수 있습니다. 초기화 해제 기는 매개 변수를 사용하지 않으며 괄호없이 작성됩니다.

deinit {
    // perform the deinitialization
}

2

할당 해제 전에 관찰자를 제거해야합니다. 그렇지 않으면 충돌이 발생합니다. 사용하여 수행 할 수 있습니다

deinit {
    // perform the deinitialization
    print("deinit")

    removeObserver(self, forKeyPath: kSelectedViewControllerKey, context: nil)
    removeObserver(self, forKeyPath: kSelectedIndexKey, context: nil)

}

-2

deinit 에서 다른 클래스의 메소드를 호출 할 때 충돌 할 수 있으므로주의하십시오.


1
반드시 그런 것은 아닙니다. 에서 심판. docs : deinitializer가 호출 될 때까지 인스턴스가 할당 해제되지 않기 때문에 deinitializer는 호출 된 인스턴스의 모든 속성에 액세스 할 수 있으며 해당 속성에 따라 동작을 수정할 수 있습니다 (예 : 필요한 파일 이름 조회) 폐쇄).
superjos
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.