I have a simple viewController that I want to listen for UIKeyboardWillHideNotification
. Therefore I have the following code:
- (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];
}
I'm trying to decide when to remove the viewController as an notification center observer. I only need to know about the UIKeyboardWillHideNotification
when the viewcontroller is on screen, thus I'm thinking about adding the following:
- (void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Is this sufficient? Is there ever a chance that viewDidUnload
or dealloc
will get called while the viewController is still on screen? Note that I'm using a very basic UINavigationController
for the flow of my app.
To answer your direct question,
dealloc
will never be called while your view is still on screen unless you directly call it which you shouldn't be.dealloc will only be called when there are no strong pointers remaining that point to your viewController.
As Anoop Vaidya suggests, it is totally doable to put removeObserver in
dealloc
and be confident thatdealloc
won't get called while your viewController is on screen, and if it does... well you have much bigger problems than removing an observerEdit: Since I can't actually reply to comments yet, when your viewController is off screen it is actually deallocated. It is then re-instantiated when it is called back on screen.
Edit: I'm wrong
Registering the notification in
viewWillAppear
and unregistering it inviewWillDisappear
seems to be a clean and symmetric solution to me.Note that
viewWillAppear
can be called multiple times beforedealloc
(e.g. if another view controller is pushed onto your VC, or if you switch between tab bar controllers.) If you register the notification inviewWillAppear
and unregister it only indealloc
then you will get duplicate registrations (compare Warning for iOS/iPhone users about duplicate NSNotification observations) and the registered selector is called multiple times for a single notification event.I actually prefer the block-based observer registration method
which returns an opaque object which is used for removing the observer again. Storing this return value into an instance variable of your view controller helps to keep track if the observer is already registered or not, and therefore helps to avoid duplicate registrations.