Where to remove observer for NSNotification in Swift?

随声附和 提交于 2019-12-17 08:53:30

问题


Where should I remove the observer for NSNotification in Swift, since viewDidUnload and dealloc() are unavailable?


回答1:


Use below method which functions same as dealloc.

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

A deinitializer is called immediately before a class instance is deallocated. You write deinitializers with the deinit keyword, similar to how intializers are written with the init keyword. Deinitializers are only available on class types.

Swift Deinitializer




回答2:


As of iOS 9 (and OS X 10.11), you don't need to remove observers yourself, if you're not using block based observers though. The system will do it for you, since it uses zeroing-weak references for observers, where it can.

And if you are using block based observers, make sure you capture self weakly using [weak self] in the closure's capture list, and remove observer in deinit method. If you don't use weak reference to self, deinit method (and thus removal of that observer) will never be called since Notification Center will hold a strong reference to it indefinitely.

More info can be found at Foundation Release Notes for OS X v10.11 and iOS 9.

If the observer is able to be stored as a zeroing-weak reference the underlying storage will store the observer as a zeroing weak reference, alternatively if the object cannot be stored weakly (i.e. it has a custom retain/release mechanism that would prevent the runtime from being able to store the object weakly) it will store the object as a non-weak zeroing reference. This means that observers are not required to un-register in their deallocation method.

Block based observers via the -[NSNotificationCenter addObserverForName: object: queue: usingBlock] method still need to be un-registered when no longer in use since the system still holds a strong reference to these observers.




回答3:


You can use three methods:

  1. after popViewController, back navigationController or dismissViewControllerAnimated:

    deinit {
        print("Remove NotificationCenter Deinit")
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
  2. viewDidDisappear, remove after it is already the next view controller:

    override func viewDidDisappear(animated: Bool) {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
  3. viewWillDisappear - before opening the next view:

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

Swift 3.0 syntax:

NotificationCenter.default.removeObserver(self)



回答4:


In Swift 4.2, this is one of the way you can remove observer

deinit {
    NotificationCenter.default.removeObserver(self, name: Notification.Name.Identifier, object: nil)
}

setup addObserver notification in viewDidLoad class

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(didReceivedItemDetail), name: Notification.Name.Identifier, object: nil)
}



回答5:


Swift provides a deinit method that is called on instances of classes before they are destroyed.

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




回答6:


I also want to point out that you should use this method:

func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name?, object anObject: Any?)

Instead of

func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: @escaping (Notification) -> Void) -> NSObjectProtocol

The latter will not remove the observer (Ran into this problem recently). The former will remove the observer if you are using iOS9.




回答7:


It is also good if you add your observer in viewWillAppear() and remove them in viewWillDisappear()




回答8:


deinit {
    NotificationCenter.default.removeObserver(self)
}


来源:https://stackoverflow.com/questions/28689989/where-to-remove-observer-for-nsnotification-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!