如何避免添加多个NSNotification观察者?

Boo*_*oon 40 cocoa ios

现在,API似乎没有提供检测是否已为特定NSNotification添加观察者的方法.什么是避免添加多个NSNotification观察者的最佳方法,而不是在你的头上保持一个标志以跟踪?有没有人已经创建了一个类别来促进这个?

fut*_*te7 71

防止添加重复观察者的一种方法是在再次添加之前显式调用目标/选择器的removeObserver.我想你可以把它添加为一个类别方法:

@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
Run Code Online (Sandbox Code Playgroud)

这假定您只为每个目标添加一个唯一的观察者以获取任何通知名称,因为它将删除该通知名称的任何现有观察者.

  • @XJones这与发布给一个且只有一个观察者的通知没有关系.这与观察者没有两次观察同一通知有关.使用此方法,您仍然可以拥有多个通知观察者. (4认同)
  • 目标变量指示运行时应查找对象的位置.我将arg名称目标更改为观察者,以消除任何可能的混淆. (3认同)
  • 是的,我误解了这个问题。这个答案确实解决了 OP 的问题,但感觉有点像解决根本问题的方法 - 例如,为什么对象开始多次观察相同的通知? (2认同)

dim*_*iax 19

斯威夫特3,4:

import Foundation

extension NotificationCenter {
    func setObserver(_ observer: AnyObject, selector: Selector, name: NSNotification.Name, object: AnyObject?) {
        NotificationCenter.default.removeObserver(observer, name: name, object: object)
        NotificationCenter.default.addObserver(observer, selector: selector, name: name, object: object)
    }
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特2:

import Foundation

extension NSNotificationCenter {
    func setObserver(observer: AnyObject, selector: Selector, name: String?, object: AnyObject?) {
        NSNotificationCenter.defaultCenter().removeObserver(observer, name: name, object: object)
        NSNotificationCenter.defaultCenter().addObserver(observer, selector: selector, name: name, object: object)
    }
}
Run Code Online (Sandbox Code Playgroud)


use*_*776 5

赞成的答案 extension NotificationCenter { ... }对我不起作用,因为我的应用程序在每次发布通知时都在创建一个新的 viewController 实例(它有一个通知观察者),因此在 viewController 的新实例上删除观察者显然不会工作。具有通知观察者的 viewController 的先前实例被调用。

以下对我有用,因为这会在视图消失后立即删除通知观察器。

// 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)


}
Run Code Online (Sandbox Code Playgroud)

  • 最好在`viewDidAppear` 中添加Observer 而不是`viewWillAppear`。 (2认同)