是的,这将删除观察者为 self
的所有注册。在NSNotificationCenter Class Reference中有记录:
以下示例说明如何取消注册所有以前已注册的通知的 someObserver
:
[[NSNotificationCenter defaultCenter] removeObserver:someObserver]
请注意,在理论上(至少截至iOS 7.0),
UIViewController
可能有自己不想在
viewWillDisappear:
中移除的注册。 它不太可能使用
addObserver:selector:name:object:
注册公共 API 中的任何通知,因为这会导致您无法在您的
UIViewController
子类中注册它们,但它现在或将来可能会注册非公共通知。
一个安全的注销方法是为每个注册发送一次
removeObserver:name:object:
:
- (void)deregisterForKeyboardNotifications {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
[center removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self deregisterForKeyboardNotifications];
}
- (void)dealloc {
[self deregisterForKeyboardNotifications];
}
另一种方法是使用addObserverForName:object:queue:usingBlock:
来注册(而不是addObserver:selector:name:object:
)。每次注册都会返回一个新的观察者对象引用。您必须保存它们(也许在一个NSArray
实例变量中,如果您不想创建单独的实例变量)。然后将每个观察者对象传递给removeObserver:
以注销其通知。例如:
@implementation MyViewController {
NSMutableArray *observers;
}
- (void)registerForKeyboardNotifications {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
NSOperationQueue *queue = [NSOperationQueue mainQueue];
__weak MyViewController *me = self;
observers = [NSMutableArray array];
[observers addObject:[center addObserverForName:UIKeyboardWillShowNotification
object:nil queue:queue usingBlock:^(NSNotification *note) {
[me keyboardWillShow:note];
}]];
[observers addObject:[center addObserverForName:UIKeyboardWillHideNotification
object:nil queue:queue usingBlock:^(NSNotification *note) {
[me keyboardWillHide:note];
}]];
[observers addObject:[center addObserverForName:UIApplicationWillResignActiveNotification
object:nil queue:queue usingBlock:^(NSNotification *note) {
[me applicationWillResignActive:note];
}]];
}
- (void)deregisterForKeyboardNotifications {
for (id observer in observers) {
[[NSNotificationCenter defaultCenter] removeObserver:observer];
}
observers = nil;
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self deregisterForKeyboardNotifications];
}
- (void)dealloc {
[self deregisterForKeyboardNotifications];
}
由于addObserverForName:object:queue:usingBlock:
返回的每个观察者都是一个新对象,只有一个注册,因此每次调用removeObserver:
都只保证移除该观察者的一个注册。
iOS 9 / macOS 10.11及更高版本的更新
从iOS 9和macOS 10.11开始,如果观察者被释放,NSNotificationCenter
会自动取消其注册。如果您的部署目标为iOS 9或更高版本或macOS 10.11或更高版本,则不再需要在dealloc
方法(或Swift中的deinit
)中手动取消注册。