Ответ 1
Да, это приведет к удалению всех регистраций, где наблюдатель self
. Он задокументирован в справочнике классов NSNotificationCenter:
В следующем примере показано, как
someObserver
регистрациюsomeObserver
для всех уведомлений, для которых он ранее зарегистрировался:[[NSNotificationCenter defaultCenter] removeObserver:someObserver];
Обратите внимание, что в теории (но не, насколько я знаю, на практике, как iOS 7.0), UIViewController
может иметь свои собственные регистрации, которые он не хочет удалять в viewWillDisappear:
Он вряд ли зарегистрируется для любого из уведомлений в публичном API с помощью addObserver:selector:name:object:
потому что это помешает вам зарегистрироваться для них в вашем подклассе UIViewController
, но он может, безусловно, зарегистрироваться для непубличных уведомлений сейчас или в будущая версия.
Безопасный способ removeObserver:name:object:
регистрации - отправить 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
экземпляра NSArray
если вы не хотите создавать отдельные переменные экземпляра). Затем вы передаете каждый из них на removeObserver:
чтобы 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
автоматически NSNotificationCenter
регистрацию наблюдателя, если наблюдатель освобождается. Вам больше не нужно отменять регистрацию вручную в своем методе dealloc
(или deinit
в Swift), если целью развертывания является iOS 9 или более поздняя версия или macOS 10.11 или новее.