Search code examples
iphoneobjective-cioscocoa-touchnsnotifications

When to unsubscribe from a NSNotification in a UIView


I am using the following NSNotifications within a UIView so that the view can be notified when a UIKeyboard appears and adjust its position (frame) on screen:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];

The two notifications above are being subscribed to within the -init method of the UIView. Where is the best place to unsubscribe from these notifications once the view has disappeared off-screen? At the moment the app is crashing whenever the UIKeyboard appears in another view, presumably because a notification is still being sent to the then released UIView.

Also, is there a better place to be subscribing to the notifications, apart from within the -init method?

Thanks for any assistance.


Solution

  • -[UIView willMoveToWindow:] and -[UIView didMoveToWindow] are called even when a view is removed from a window. The window argument (or the window property in the case of -didMoveToWindow) will be nil in that case, i. e.:

    - (void)willMoveToWindow:(UIWindow *)newWindow {
        if (newWindow == nil) {
            // Will be removed from window, similar to -viewDidUnload.
            // Unsubscribe from any notifications here.
        }
    }
    
    - (void)didMoveToWindow {
        if (self.window) {
            // Added to a window, similar to -viewDidLoad.
            // Subscribe to notifications here.
        }
    }
    

    Except for a few edge cases this is a safe way to do it. If you need more control, you can observe the hidden property of the window to which your view belong.