Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 276
Skoota Avatar asked Nov 20 '11 10:11

Skoota


People also ask

Do you need to remove observers Swift?

If your app targets iOS 9.0 and later or macOS 10.11 and later, and you used addObserver(_:selector:name:object:) , you do not need to unregister the observer. If you forget or are unable to remove the observer, the system cleans up the next time it would have posted to it.

How do I delete a specific observer in Swift?

Removing registered observer For Selector approach, use NotificationCenter. default. removeObserver(self, name: notificationName , object: nil) , to remove the observer.


2 Answers

-[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.

like image 56
gcbrueckmann Avatar answered Sep 18 '22 12:09

gcbrueckmann


I put my removeObserver: calls in -dealloc.

Haven't had any problems so far.

like image 24
Tom Irving Avatar answered Sep 19 '22 12:09

Tom Irving