最近在用通知执行某方法的时候,遇到了一个发送一次通知却多次执行通知方法的问题。
问题再现
1、注册通知(添加观察者),这里采用的是block回调方式去执行通知方法,而并非常用的addObserver:selector:name:object:
[[NSNotificationCenter defaultCenter] addObserverForName:URLookExpandCloth object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
// 执行你想做的事情
}];
2、发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:URLookExpandCloth object:nil];
3、移除通知
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
结果
通知方法的block回调多次执行。
问题原因
这是因为移除通知的地方不对,不应该采用 [[NSNotificationCenter defaultCenter] removeObserver:self];这种方式去移除,因为这里采用的注册通知的方式是block,平常我们注册通知一般是这样做:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(xxxx:) name: URLookExpandCloth object:nil];
这两种注册通知的方法区别在于,block方式有返回值,addObserver没有返回值,block那种方式,返回值实际上就是观察者,我们必须用一个对象去接收这个返回值,然后再移除该返回值(观察者)
解决办法
改的实际上就是上面的第一步和第三步
1、先定义一个全局属性,用于接收注册通知时的返回值
@property (nonatomic, strong) id noty;
2、
_noty = [[NSNotificationCenter defaultCenter] addObserverForName:URLookExpandCloth object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
// 执行你想做的事情
}];
3、移除通知
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:_noty];
}
网友评论