및 사용할 수 없기 NSNotification
때문에 Swift 에서 관찰자를 어디에서 제거해야 합니까?viewDidUnload
dealloc()
답변:
와 동일한 기능을하는 아래 방법을 사용하십시오 dealloc
.
deinit {
// Release all resources
// perform the deinitialization
}
deinitializer는 클래스 인스턴스가 할당 해제되기 직전에 호출됩니다. init 키워드를 사용하여 intializer를 작성하는 방법과 비슷하게 deinit 키워드를 사용하여 deinitizer를 작성합니다. Deinitializer는 클래스 유형에서만 사용할 수 있습니다.
deinit
ViewControllerA에 대한 @Kampai 메서드는 ViewControllerB를 푸시 할 때 호출되지 않습니다.
deinit
ViewControllerA는 탐색 컨트롤러의 스택에 없을 때만 호출됩니다. 예 : rootViewController로 전환 (rootViewController가 ViewControllerA가 아닌 경우)
deinit
을 하지 않을 가능성이 높습니다 . 것 호출에 이상적인 장소func viewDidDisappear(_ animated: Bool)
현재 아이폰 OS 9 (및 OS X 10.11), 당신은 관찰자를 제거 할 필요가 없습니다 당신은 블록 기반의 관찰자하지만 사용하지 않을 경우, 자신을. 시스템은 관찰자를 위해 제로화 약한 참조를 사용하기 때문에 가능합니다.
그리고 블록 기반 관찰자를 사용 하는 경우 클로저의 캡처 목록에서 자신을 약하게[weak self]
캡처 하고 메서드 에서 관찰자 를 제거하십시오deinit
. self에 대한 약한 참조를 사용하지 않으면 deinit
알림 센터가 무기한으로 강력한 참조를 보유하므로 메소드 (따라서 해당 관찰자 제거)가 호출되지 않습니다.
자세한 내용 은 OS X v10.11 및 iOS 9 용 Foundation Release Notes 에서 확인할 수 있습니다 .
관찰자가 영점 약한 참조로 저장 될 수있는 경우 기본 저장소는 관찰자를 영점 약한 참조로 저장합니다. 또는 객체를 약하게 저장할 수없는 경우 (즉, 런타임을 방지하는 사용자 지정 유지 / 해제 메커니즘이 있습니다.) 개체를 약하게 저장할 수 없음) 개체를 약하지 않은 제로화 참조로 저장합니다. 이것은 옵저버가 할당 해제 방법에서 등록을 취소 할 필요가 없음을 의미합니다.
-[NSNotificationCenter addObserverForName : object : queue : usingBlock] 메서드를 통한 블록 기반 관찰자는 시스템이 여전히 이러한 관찰자에 대한 강력한 참조를 보유하고 있기 때문에 더 이상 사용하지 않을 때 등록 해제해야합니다.
delegate = nil
했습니다 dealloc()
. 지금부터 똑같이 작동합니까?
세 가지 방법을 사용할 수 있습니다.
후 popViewController
, 뒤 navigationController
또는 dismissViewControllerAnimated
:
deinit {
print("Remove NotificationCenter Deinit")
NSNotificationCenter.defaultCenter().removeObserver(self)
}
viewDidDisappear
, 이미 다음 뷰 컨트롤러가 된 후 제거하십시오.
override func viewDidDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
viewWillDisappear
-다음보기를 열기 전 :
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
Swift 3.0 구문 :
NotificationCenter.default.removeObserver(self)
Swift 4.2에서 이것은 관찰자를 제거 할 수있는 방법 중 하나입니다.
deinit {
NotificationCenter.default.removeObserver(self, name: Notification.Name.Identifier, object: nil)
}
viewDidLoad 클래스에서 addObserver 알림 설정
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(didReceivedItemDetail), name: Notification.Name.Identifier, object: nil)
}
Swift는 파괴되기 전에 클래스의 인스턴스에서 호출되는 deinit 메소드를 제공합니다.
또한이 방법을 사용해야한다는 점을 지적하고 싶습니다.
func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?)
대신에
func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Void) -> NSObjectProtocol
후자는 관찰자를 제거하지 않을 것입니다 (최근에이 문제에 빠졌습니다). iOS9을 사용하는 경우 전자는 관찰자를 제거합니다.
dealloc
합니다.
스위프트 5
채팅 응용 프로그램이 있으므로 ChatLogViewController에서 다른 viewController로 이동 한 다음 돌아올 때마다 키보드 알림에 대한 추가 관찰자가 1 명 있습니다. 이를 제거하려면 viewController를 변경 하거나 chatLogViewController에서 사라질 때 모든 관찰자를 제거합니다 .
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}