Objective-C Where to remove observer for NSNotification?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
In Objective-C, every call to addObserver: on NSNotificationCenter must be balanced with a corresponding removeObserver: to prevent crashes and memory leaks. The best place to remove observers depends on the object's lifecycle: for view controllers, use dealloc (or viewWillDisappear: if the observer is view-lifecycle-dependent). Since iOS 9, NSNotificationCenter automatically removes observers when the object is deallocated for name-based registrations, but block-based observers still require manual removal. Understanding these rules prevents the two most common notification bugs: messages sent to deallocated objects, and duplicate observer registrations.
Adding and Removing Observers
removeObserver:self in dealloc removes all notification registrations for this object, regardless of notification name or sender.
Where to Remove: dealloc vs viewWillDisappear
Use dealloc when the observer should live as long as the object exists. Use viewWillAppear/viewWillDisappear when the observer should only be active while the view is on screen (e.g., to avoid updating a hidden view controller's UI).
Block-Based Observers (Require Manual Removal)
Block-based observers return an opaque token object. This token — not self — is the observer. You must store it and remove it explicitly. The iOS 9 automatic cleanup does not apply to block-based observers.
iOS 9+ Automatic Cleanup
Starting with iOS 9, NSNotificationCenter uses weak references for selector-based observers. When the observer object is deallocated, the notification center automatically removes the registration:
Swift Equivalent
Note the [weak self] capture list in the block — without it, the block retains self, creating a retain cycle that prevents deinit from ever being called.
Removing Specific vs All Observers
Using removeObserver:self without specifying a name removes all registrations, which is safe in dealloc but can accidentally remove observers registered by superclasses or categories if called elsewhere.
Common Pitfalls
- Not removing block-based observers: Block-based observers (created with
addObserverForName:object:queue:usingBlock:) are not automatically cleaned up on iOS 9+. The returned token must be stored and explicitly removed indealloc/deinit, or the block continues to execute after the intended receiver is gone. - Creating a retain cycle with block-based observers: The block captures
selfstrongly by default. Ifselfalso holds a strong reference to the token, neither can be deallocated. Use__weak typeof(self) weakSelf = selfin Objective-C or[weak self]in Swift inside the block. - Registering observers multiple times without removing: Calling
addObserver:inviewWillAppear:without a matchingremoveObserver:inviewWillDisappear:registers a new observer each time the view appears. The notification handler fires multiple times — once per registration. - Calling
removeObserver:selfoutside ofdealloc: Removing all observers withremoveObserver:selfin methods likeviewWillDisappear:can accidentally unregister observers added by parent classes, UIKit internals, or categories. Remove specific notifications by name instead. - Assuming iOS 9 auto-cleanup handles everything: While iOS 9+ automatically removes selector-based observers at dealloc, explicit removal is still a best practice. It makes the code self-documenting, handles block-based observers, and ensures observers stop before dealloc if needed.
Summary
- Remove selector-based observers in
deallocwith[[NSNotificationCenter defaultCenter] removeObserver:self] - Remove block-based observers by storing the returned token and calling
removeObserver:tokenindealloc - Use
viewWillAppear:/viewWillDisappear:pairs when the observer should only be active while the view is visible - iOS 9+ automatically cleans up selector-based observers, but block-based observers must always be removed manually
- Use
[weak self](Swift) or__weak(Objective-C) in notification blocks to prevent retain cycles - Prefer removing specific notifications by name over blanket
removeObserver:selfoutside ofdealloc
Related reading
- Objective C - Assign, Copy, Retain
- Octave logistic regression difference between fmincg and fminunc
- Octave logistic regression difference between fmincg and fminunc
- oh-my-zsh slow, but only for certain Git repo
- Obscure a UITextField password
- Obscure a UITextField password
- Ok to have stack depth linearly proportional to some input size?
- Oklogk time algorithm to find kth smallest element from a binary heap

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.