Observer <object> was not registered as an observer – duplicate removeObserver call
0 reputation · 17 Jun 2023, 09:42 UTC
0 reputation · 17 Jun 2023, 09:42 UTC
When developing with Foundation’s NSNotificationCenter, developers often need to clean up observers in deinit or cleanup routines. Calling removeObserver:name:object: on an object that has already been removed, or never added, raises an NSInvalidArgumentException with the message “Observer was not registered as an observer”. The decision point is whether to add a defensive check before each removal or to let the exception propagate and handle it elsewhere.
Considerations include the impact on performance, the desire to keep crash‑free logs, and the lack of a built‑in method to query an observer’s registration state. The framework documentation does not prescribe a standard pattern, leaving the choice to individual projects.
What are the recommended strategies to avoid this exception without introducing unnecessary overhead? Is it acceptable to wrap the call in a try/catch block, or should a custom registration tracker be maintained? How do other Apple frameworks handle similar cleanup scenarios?
29275 reputation · 17 Jun 2023, 10:51 UTC
The exception is thrown when removeObserver:name:object: (or the variant with a specific name/object) is invoked for an observer that is either never registered via addObserver or has already been removed. The notification center searches its internal list; if the observer entry is not found it raises NSInvalidArgumentException with the message “Observer was not registered as an observer”.
removeObserver will raise an exception if the observer is not registered for the given name/object combination.removeObserver(_:) (i.e., remove the observer from all notifications) does **not** raise an exception when the observer has no registrations; it simply does nothing.deinit (or your cleanup routine):
deinit {
NotificationCenter.default.removeObserver(self)
}
This safely clears any registrations without risking the exception, regardless of how many (or zero) observers were added.
addObserver call succeeded. Only call removeObserver:name:object: when the flag indicates the observer is currently registered.
If you are using the specific removeObserver:name:object: form and cannot change to the blanket removal, confirm whether you are observing the same notification name and object each time. Knowing whether the name/object pair is constant will determine if a single flag is sufficient or if you need a more granular tracking structure.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.