There are several resources (blog, SO question, plus I've seen it used everywhere) that recommend removing an observer from the NotificationCenter
in the deinit
of the UIViewController
, e.g.:
deinit {
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
Now while according to another blog entry I don't have to care about removing an observer from NotificationCenter
since it uses weak
references, I've seen the same pattern used with other references.
The question that bugs me. According to official documentation:
A deinitializer is called immediately before a class instance is deallocated. You write deinitializers with the deinit keyword, similar to how initializers are written with the init keyword. Deinitializers are only available on class types.
Doesn't this mean that if there still is a strong reference to the class, deinit
will not get called, thus rendering the deinit
references cleanup useless? If there is still a strong reference to the viewController
from the NotificationCenter
, then viewController
's deinit
will never get called, right? So removing the strong refenreces in deinit
can never really work.
Am I missing something here?
This statement
was true in the past.
And your statement
is correct.
Observers have weak reference
An observer holds a
weak reference
to the target object.This explain why the
deinit
of an object will be called even if there are multiple active observers.So why do we want to remove the observers in the deinit?
This was needed prior to iOS 9 to prevent an observer from invoking a method of a deallocated object.
However unregistering an observer is no longer needed from macOS 10.11 and iOS 9.0
Source