在清除正确的模式中清理强引用?
有几种资源( 博客 , SO问题 ,加上我已经看到它在任何地方使用)建议从UIViewController
的deinit
中删除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
的强引用,那么viewController
的deinit
永远不会被调用,对吧? 因此,去除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将不再向可能已解除分配的已注册观察者发送通知。
资源