为啥你必须在 ios8 中删除观察者?

Posted

技术标签:

【中文标题】为啥你必须在 ios8 中删除观察者?【英文标题】:why do you have to remove observer in ios8?为什么你必须在 ios8 中删除观察者? 【发布时间】:2016-09-23 15:04:03 【问题描述】:

在阅读了this ios 9 的帖子后,我知道您不再需要 removeObserver。

然而对于 iOS 8,你 needed 到 viewController 的 deinit 方法中的 removeObserver。 但我无法理解它。如果 viewController 被释放,那么它不是 DEAD 吗?为什么我们需要做一个removeObserver。做旁观者就像打电话给一个永远不会接电话的死人

我不明白什么?

【问题讨论】:

因为向解除分配的实例发送消息会使应用程序崩溃... 【参考方案1】:

您链接的文章中对此进行了充分解释:

通知中心现在保持对观察者的归零引用:

如果观察者能够被存储为清零弱引用,则底层存储会将观察者存储为清零弱引用,或者如果对象不能被弱存储(即它具有自定义保留/释放机制,将防止运行时能够弱存储对象)它将对象存储为非弱归零引用。

在 iOS 9 之前,NSNotificationCenter 未使用 weak 引用实现,因此 NSNotificationCenter 不知道目标已被释放。它盲目地向任何已注册的目标发送通知。如果目标已被释放,这很糟糕(可能会崩溃)。因此需要始终取消注册。

在 iOS 9 中,NSNotificationCenter 开始使用弱引用。这意味着它现在知道注册目标之一是否已被释放。这意味着它不再尝试向解除分配的目标发送通知。这意味着您不再需要在目标被释放之前显式取消注册。

【讨论】:

1. 在 iOS 9 之前,NSNotificationCenter 没有使用弱引用实现,因此 NSNotificationCenter 不知道目标已被释放。 在 iOS8 中,notificationCenter 不是持有对该对象的强引用吗?因此,即使所有其他引用都删除了它们的引用,notificationCenter 仍会保留它。那么对象是如何被释放的呢? 2.“归零参考”是什么意思?这只是意味着弱参考吗? “非弱归零”是什么意思?无主?【参考方案2】:

作为一个旁观者就像给一个永远不会接电话的死人打电话

没错!

在这种情况下,您的电话号码是一个内存地址,一旦通知中心尝试呼叫观察者,它将被取消引用。现在,一旦 View Controller 被释放,你期望这个内存地址是什么?我们不知道。

但您当然不想在可能不再存在或什至已被完全不同的东西(例如图像)替换的对象上调用方法(这就是通知中心所做的)。

添加一个真实世界的示例:这更像是依赖于您的汽车(视图控制器)位于车库中的特定位置(内存地址)。你绝对依赖你的车在那里,所以当你想上车时你甚至都不看它是否在那里。现在,假装有人移除(解除分配)你的车,但你仍然依赖它在那里。坐上一辆已经不存在的汽车肯定会是一种痛苦的经历。

【讨论】:

以上是关于为啥你必须在 ios8 中删除观察者?的主要内容,如果未能解决你的问题,请参考以下文章

java常用设计模式-观察者模式

为啥用示波器观察ARM的SPI 的时钟始终维持高电平啊。怎么才能有时钟信号输出???

如何在MVVM架构中观察RecyclerView适配器中的LiveData?

设计模式-观察者

Angularjs:为啥 1 个绑定有 3 个观察者?

MATLAB中HMM函数SEQ(观察序列的值)必须是正整数吗