如何停止NSNotification中的观察器被调用两次?

我有一个两次调用NSNotification的观察者。 我不知道该怎么办

我GOOGLE了,但没有find解决办法。

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(connectedToServer:) name:@"ConnectedToServer" object:nil]; - (void)connectedToServer:(NSNotification*)notification { [[NSNotificationCenter defaultCenter] postNotificationName:@"SendMessageToServer" object:message]; } 

解决scheme1:首先是检查通知本身是否发布两次。

解决scheme2:即使通知只发布一次,也会多次添加通知的观察者(无论通知是否相同)。 例如,以下两行将为相同的通知( aSelector )注册观察者( self )两次。

 [[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil]; 

你必须find第二次添加观察者的位置,并将其删除。 还要确保你所添加的代码不会被调用两次。

解决scheme3:如果您不确定是否已添加观察者,则可以简单地执行以下操作。 这将确保观察者只添加一次。

 [[NSNotificationCenter defaultCenter] removeObserver:self name:aName object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil]; 

如果您的addObserver方法运行多次,它将创build多个观察者。 我的问题是,我以某种方式将我的观察者置于viewWillAppear ,在我发布通知之前出现了多次,并导致我的观察者被多次调用。

虽然EmptyStack的第三个解决scheme有效,但您的观察者被调用两次是有原因的,所以通过查找它,可以防止不必要的代码行,而不是删除和添加同一个观察者。

我build议把你的观察者放在viewDidLoad以避免像我经历过的那样简单的错误。

尝试在viewWillDisappear方法中移除Observer:

 -(void)viewWillDisappear:(BOOL)animated{ [[NSNotificationCenter defaultCenter] removeObserver:self name:@"startAnimating" object:nil]; } 

尝试在[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil];上设置一个断点[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil]; 并检查是否被多次调用。

对于那些在Swift 2.2或更高版本中寻找解决scheme的人来说,像我这样的人可以创build一个扩展,如下所示:

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

你可以调用这个方法如下:

 NSNotificationCenter.defaultCenter().setObserver(self, selector: #selector(methodName), name: "name", object: nil) 

如果存在的话,扩展将处理以前观察者的移除。 即使没有以前的观察者在场,这段代码也不会崩溃。