在清除正确的模式中清理强引用?

有几种资源( 博客 , SO问题 ,加上我已经看到它在任何地方使用)建议从UIViewControllerdeinit中删除NotificationCenter中的deinit ,例如:

 deinit { NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil) } 

现在,根据另一篇博客文章,我不必关心从NotificationCenter删除观察者,因为它使用weak引用,我看到了与其他引用一起使用的相同模式。

这个问题让我烦恼。 根据官方文件 :

在取消分配类实例之前立即调用deinitializer。 您使用deinit关键字编写deinitializers,类似于使用init关键字编写初始化程序的方式。 Deinitializers仅适用于class级类型。

这是不是意味着如果仍然有一个强引用类, deinit将不会被调用,从而使deinit引用清理无用? 如果NotificationCenter仍然存在对viewController的强引用,那么viewControllerdeinit永远不会被调用,对吧? 因此,去除deinit中强大的refenreces永远不会真正起作用。

我在这里错过了什么吗?

这个说法

[…]建议在UIViewController的deinit中从NotificationCenter中删除观察者[…]

过去是真的。

还有你的陈述

[…]如果仍然有强烈的类参考,deinit将不会被调用。

是正确的。

观察者的参考不足

观察者持有对目标对象的weak reference

这解释了为什么即使有多个活动观察者也会调用对象的deinit

那么为什么我们要删除deinit中的观察者呢?

在iOS 9之前需要这样做以防止观察者调用解除分配对象的方法。

但是,不再需要从macOS 10.11和iOS 9.0取消注册观察者

在OS X 10.11和iOS 9.0中,NSNotificationCenter和NSDistributedNotificationCenter将不再向可能已解除分配的已注册观察者发送通知。

资源