Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to safely removeObserver (Swift)

Tags:

ios

swift

I have added an observer

override func viewDidLoad()
{
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector:"selector name", name: "observer name", object:nil)
    ...
}

When removing observer in deinit,

deinit
{
    NSNotificationCenter.defaultCenter().removeObserver(self, forKeyPath: <some string>)
}

the app sometimes crashes:

Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer "class" for the key path "some string" from NSNotificationCenter because it is not registered as an observer.


So I am trying to add do/catch

deinit
{
    do{
        try NSNotificationCenter.defaultCenter().removeObserver(self, forKeyPath: <some string>)
    }catch{}
}

But I get a warning:

catch block is unreachable because no errors are thrown in do block

And the app crashes


and when I am adding a try

deinit
{
    do{
        try NSNotificationCenter.defaultCenter().removeObserver(self, forKeyPath: <some string>)
    }catch{}
}

I get this warning:

no calls to throwing functions occur within try expresion

And the app crashes

How should that be done?

like image 747
Luda Avatar asked Nov 19 '15 16:11

Luda


People also ask

Do you need to remove observers Swift?

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.

How do I delete an observer in Objective-C?

I'd recommend, that you add a call [notificationCenter removeObserver: self] in method dealloc of those classes, which you intend to use as observers, as it is the last chance to unregister an observer cleanly. This will, however, only protect you against crashes due to the notification center notifying dead objects.


2 Answers

I think you should use code

NSNotificationCenter.defaultCenter().removeObserver(self)

Explain: You have mistake here: You are using NSNotification & NSNotificationCenter so you have to using this code above to remove observe. you have use code for KVO to remove observer so it will wrong.

More detail you can read at here. Key-Value-Observing

like image 131
vien vu Avatar answered Oct 21 '22 17:10

vien vu


If you support iOS Versions by 9.0 you don't need to remove observers by yourself in your deinit method.

Taken from the documentation

In OS X 10.11 and iOS 9.0 NSNotificationCenter and NSDistributedNotificationCenter will no longer send notifications to registered observers that may be deallocated.

https://useyourloaf.com/blog/unregistering-nsnotificationcenter-observers-in-ios-9/

like image 20
Ilker Baltaci Avatar answered Oct 21 '22 15:10

Ilker Baltaci