在清除正确的模式时清理强大的参考?

时间:2017-12-10 18:07:41

标签: ios swift automatic-ref-counting retain-cycle deinit

有几种资源(blogSO question,以及我已经看到它在任何地方使用过)建议从NotificationCenter deinit中移除观察者UIViewController的内容,例如:

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

现在根据another blog entry我不必关心从[{1}}移除观察员,因为它使用NotificationCenter引用,我看到了相同的模式与其他参考文献一起使用。

让我烦恼的问题。根据官方documentation

  

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

这是否意味着如果仍然存在对该类的强引用,则weak将不会被调用,从而使deinit引用清理无效?如果deinit中仍然存在对viewController的强烈引用,那么NotificationCenter viewController永远不会被调用,对吧?因此,删除deinit中强大的重新删除功能永远无法正常工作。

我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:2)

本声明

  

[...]建议从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将不再向可能已解除分配的已注册观察者发送通知。

Source