Search code examples
iosswiftxcodedestructorapplication-lifecycle

Should deinit be overridden to remove observers in Swift?


Team mates written code like,

deinit {
    NotificationCenter.default.removeObserver(self)
}

I commented to remove this as observers are already taken care by the framework. Team mates want to keep this code if no side effect. Now, even if we keep this above code is there any side effect?

Should I also call super.deinit() inside deinit?


Solution

  • As of iOS 9 , you don't need to remove observers yourself, if you're not using block based observers though. The system will do it for you, since it uses zeroing-weak references for observers, where it can.

    If the observer is able to be stored as a zeroing-weak reference the underlying storage will store the observer as a zeroing weak reference, alternatively if the object cannot be stored weakly (i.e. it has a custom retain/release mechanism that would prevent the runtime from being able to store the object weakly) it will store the object as a non-weak zeroing reference. This means that observers are not required to un-register in their deallocation method.

    Block based observers via the -[NSNotificationCenter addObserverForName: object: queue: usingBlock] method still need to be un-registered when no longer in use since the system still holds a strong reference to these observers.

    Apple Docs

    and for super.deinit() apple says

    Deinitializers are called automatically, just before instance deallocation takes place. You are not allowed to call a deinitializer yourself. Superclass deinitializers are inherited by their subclasses, and the superclass deinitializer is called automatically at the end of a subclass deinitializer implementation. Superclass deinitializers are always called, even if a subclass does not provide its own deinitializer.

    swift docs