1

有几个资源(博客SO question,加上我已经看到它在任何地方使用)建议从 中删除观察者NotificationCenterdeinit例如UIViewController

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 关键字编写反初始化器,类似于使用 init 关键字编写初始化器的方式。反初始化器仅适用于类类型。

这是否意味着如果仍然有对该类的强引用,deinit将不会被调用,从而使deinit引用清理无用?如果仍然有对viewControllerfrom 的强引用NotificationCenter,那么viewController'sdeinit将永远不会被调用,对吧?因此,删除强大的参考deinit永远不会真正起作用。

我在这里错过了什么吗?

4

1 回答 1

2

这个说法

[...] 建议在 UIViewController 的 deinit [...]

过去是真的。

还有你的陈述

[...] 如果仍然有对该类的强引用,则不会调用 deinit。

是正确的。

观察者有弱参考

一个观察者持有一个weak reference目标对象。

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

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

在 iOS 9 之前需要这样做,以防止观察者调用已释放对象的方法。

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

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

来源

于 2017-12-10T18:28:01.357 回答