How to avoid adding multiple NSNotification observer?
Solution 1:
One way to prevent duplicate observers from being added is to explicitly call removeObserver for the target / selector before adding it again. I imagine you can add this as a category method:
@interface NSNotificationCenter (UniqueNotif)
- (void)addUniqueObserver:(id)observer selector:(SEL)selector name:(NSString *)name object:(id)object {
[[NSNotificationCenter defaultCenter] removeObserver:observer name:name object:object];
[[NSNotificationCenter defaultCenter] addObserver:observer selector:selector name:name object:object];
}
@end
This assumes that the you will only add one unique observer to each target for any notification name, as it will remove any existing observers for that notification name.
Solution 2:
Swift 5:
import Foundation
extension NotificationCenter {
func setObserver(_ observer: Any, selector: Selector, name: Notification.Name, object: Any?) {
removeObserver(observer, name: name, object: object)
addObserver(observer, selector: selector, name: name, object: object)
}
}
Swift 3-4:
import Foundation
extension NotificationCenter {
func setObserver(_ observer: AnyObject, selector: Selector, name: NSNotification.Name, object: AnyObject?) {
removeObserver(observer, name: name, object: object)
addObserver(observer, selector: selector, name: name, object: object)
}
}
Swift 2:
import Foundation
extension NSNotificationCenter {
func setObserver(observer: AnyObject, selector: Selector, name: String?, object: AnyObject?) {
removeObserver(observer, name: name, object: object)
addObserver(observer, selector: selector, name: name, object: object)
}
}
Solution 3:
The Upvoted answer with extension NotificationCenter { ... }
did not work for me, since my app was creating a new instance of a viewController (this had a Notification observer) every time a notification was posted, so removing an observer on a new instance of a viewController obviously doesn't work.
Previous instances of the viewController that had Notification Observers were getting called.
The below worked for me, since this was removing the Notification Observer as soon as the view was being disappeared.
// Notification observer added
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(self.someFunc(notification:)), name: Notification.Name("myNotification"), object: nil)
}
// Notification observer removed
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self, name: Notification.Name("myNotification"), object: nil)
}