2

У меня есть простой viewController, который я хочу прослушать UIKeyboardWillHideNotification. Поэтому у меня есть следующий код:NSNotificationCenter относительно ViewWillAppear и ViewWillDisapper

- (void) viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(keyboardWillBeHidden) 
               name:UIKeyboardWillHideNotification object:nil]; 
} 

- (void) keyboardWillBeHidden 
{ 
    [self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES]; 
} 

Я пытаюсь решить, когда, чтобы удалить ViewController как уведомление центра наблюдателя. Мне нужно только знать о UIKeyboardWillHideNotification когда ViewController находится на экране, таким образом, я думаю о том, добавив следующее:

- (void) viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

Достаточно ли этого? Есть ли вероятность, что viewDidUnload или dealloc будет вызван, пока viewController все еще находится на экране? Обратите внимание, что я использую очень простой UINavigationController для потока моего приложения.

+0

Почему бы не удалитьObserver в 'dealloc'? –

+0

Я мог бы, но это кажется излишним, учитывая, что мне не нужно знать об уведомлениях, в то время как viewcontroller выключен. – Nosrettap

ответ

5

Регистрация уведомления в viewWillAppear и регистрацией его в viewWillDisappear кажется чистым и симметричное решение для меня.

Обратите внимание, что viewWillAppear можно назвать несколько раз, прежде чем dealloc (например, если другой вид контроллер помещается на ваш VC, или если вы переключаетесь между панелью вкладок контроллерами.) Если вы зарегистрировать уведомление в viewWillAppear и отменить его только в dealloc тогда вы получите дубликаты регистраций (сравните Warning for iOS/iPhone users about duplicate NSNotification observations), и зарегистрированный селектор вызывается несколько раз для одного события уведомления.

Я предпочитаю блок на основе метод регистрации наблюдателя

addObserverForName:object:queue:usingBlock: 

который возвращает непрозрачный объект, который используется для удаления снова наблюдателя. Сохранение этого возвращаемого значения в переменную экземпляра вашего контроллера просмотра помогает отслеживать, если наблюдатель уже зарегистрирован или нет, и, следовательно, помогает избежать дублирования регистрации.

+0

Так что, когда вы используете метод addObserverForName, я бы все же поместил его в 'viewWillAppear' и' viewWillDisapper'? – Nosrettap

+0

@Nosrettap: Да. Так что в этом случае это не имеет большого значения, я просто упомянул об этом как общее замечание для более сложных ситуаций. И мне нравятся блочные методы! –

+0

@MartinR есть ли у вас пример реализации с 'addObserverForName: object: queue: usingBlock:'? Большое спасибо –

0

Чтобы ответить на ваш прямой вопрос, dealloc никогда не будет вызываться, пока ваш вид все еще отображается на экране, если вы не назовете его прямым вызовом, которого вы не должны быть.

dealloc будет вызываться только тогда, когда нет сильных указателей, оставшихся, что указывает на ваш viewController.

Как следует Anoop Вайдья, это полностью выполнимо поставить removeObserver в dealloc и быть уверенным, что dealloc не дозвонились, пока ваш ViewController на экране, и если он делает ... ну у вас есть гораздо больше проблем, чем удаление a observer

Редактировать: Поскольку я еще не могу ответить на комментарии, когда ваш viewController выключен, он фактически освобожден. Затем он повторно создается, когда он возвращается на экран.

Edit: я неправильно

+0

Контроллер вида * не * автоматически освобождается и повторно создается, когда он выключен. Также вполне возможно освободить контроллер вида, пока его вид отображается на экране, потому что представление не имеет сильной ссылки на его контроллер представления. Это не должно происходить нормально, особенно с ARC, но если вы должны вручную добавить вид vc в иерархию, это может произойти довольно легко, если vc автореализован. – omz

+0

@omz: Я не понимаю твое второе предложение. Как могло случиться, что диспетчер представлений освобожден, пока его представление все еще видимо? Должны ли быть сильные ссылки на контроллер вида, когда он находится где-то в иерархии диспетчера представлений? - Хорошо, я только что видел ваше обновление комментария. Я думал только в ARC. –

+0

Mah bad, мне показалось, что я слышал это в лекциях Стэнфорда, но я по-прежнему в основном ном – Pinwheeler

Смежные вопросы