programing

Swift에서 NSNotification 관찰자를 제거할 위치는 어디입니까?

css3 2023. 8. 8. 21:45

Swift에서 NSNotification 관찰자를 제거할 위치는 어디입니까?

관찰자를 어디서 제거해야 합니까?NSNotification이후 스위프트에서viewDidUnload그리고.dealloc()사용할 수 없습니까?

iOS 9(및 OS X 10.11) 이후에는 블록 기반 관찰자를 사용하지 않는 경우에는 관찰자를 직접 제거할 필요가 없습니다.시스템은 관찰자를 위해 제로잉-취약 참조를 사용하기 때문에 가능한 경우 이를 수행할 수 있습니다.

그리고 블록 기반 관찰자를 사용하는 경우에는 다음을 사용하여 자신을 약하게 캡처해야 합니다.[weak self]폐쇄의 캡처 목록에서, 관찰자 제거deinit방법.자기 자신에 대한 약한 언급을 하지 않는다면,deinitNotification Center는 메서드에 대한 강력한 참조를 무기한 보유하므로 메서드(따라서 해당 관찰자의 제거)를 호출하지 않습니다.

자세한 내용은 OS X v10.11iOS 9용 Foundation Release Notes에서 확인할 수 있습니다.

관찰자가 영점-약점 기준으로 저장될 수 있는 경우, 기본 저장장치는 관찰자를 영점-약점 기준으로 저장할 수 있으며, 반대로 물체를 약하게 저장할 수 없는 경우(즉, 물체를 약하게 저장할 수 없는 경우).런타임이 개체를 약하게 저장할 수 없도록 하는 사용자 지정 보존/해제 메커니즘이 있습니다.) 개체를 약한 제로잉 참조가 아닌 참조로 저장합니다.즉, 관찰자는 할당 취소 방법에서 등록 취소를 할 필요가 없습니다.

-[NSNotificationCenter addObserverForName: object: queue: usingBlock] 메서드를 통한 블록 기반 관찰자는 시스템에서 여전히 이러한 관찰자에 대한 강력한 참조를 보유하고 있으므로 더 이상 사용하지 않을 때 등록 취소해야 합니다.

다음과 같은 기능을 하는 아래의 방법을 사용합니다.dealloc.

deinit {
    // Release all resources
    // perform the deinitialization
}

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

스위프트 초기화 해제기

세 가지 방법을 사용할 수 있습니다.

  1. 끝나고popViewController,뒤로navigationController또는dismissViewControllerAnimated:

     deinit {
         print("Remove NotificationCenter Deinit")
         NSNotificationCenter.defaultCenter().removeObserver(self)
     }
    
  2. viewDidDisappear이미 다음 뷰 컨트롤러가 된 후 제거:

     override func viewDidDisappear(animated: Bool) {
         NSNotificationCenter.defaultCenter().removeObserver(self)
     }
    
  3. viewWillDisappear다음 보기를 열기 전에:

     override func viewWillDisappear(animated: Bool) {
         NSNotificationCenter.defaultCenter().removeObserver(self)
     }
    

Swift 5.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 메서드를 제공합니다.

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

이 방법을 사용해야 한다는 점도 지적하고 싶습니다.

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을 사용하고 있다면 전자는 옵서버를 제거할 것입니다.

스위프트 5

채팅 응용 프로그램이 있으므로 ChatLogViewController에서 다른 ViewController로 이동했다가 다시 돌아올 때마다 키보드 알림의 옵저버가 한 개 더 있습니다.보기 컨트롤러를 변경하거나 chatLogView 컨트롤러에서 사라지면 모든 관찰자를 제거합니다.

override func viewDidDisappear(_ animated: Bool) {    
    super.viewDidDisappear(animated)

    NotificationCenter.default.removeObserver(self)
}
deinit {
    //Remove Observer 
    NotificationCenter.default.removeObserver(self)
}
deinit {
    NotificationCenter.default.removeObserver(self)
}

관자를에추것좋습다니도는에 관찰자를 .viewWillAppear()그리고 그것들을 제거합니다.viewWillDisappear()

특별한 경우에는 관찰자를 추가해야 합니다.

func viewWillAppear(_ animated: Bool)

기본 보기 컨트롤러에 팝업 보기 컨트롤러가 표시될 때 해당 컨트롤러가 있으면 Notification Center에서 관찰자를 제거하지 않기 때문입니다.사용하는 경우

func viewDidDisappear(_ animated: Bool)

팝업이 표시된 후 알림을 놓치게 됩니다!

그렇게

다음과 같은 경우 구독을 재설정해야 합니다.

func viewWillAppear(_ animated: Bool)

func가 트리거되었습니다.

언급URL : https://stackoverflow.com/questions/28689989/where-to-remove-observer-for-nsnotification-in-swift