如何停止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)
如果存在的话,扩展将处理以前观察者的移除。 即使没有以前的观察者在场,这段代码也不会崩溃。