如果对象是观察者并在通知中心注册,如何调用dealloc方法?

问题描述:

考虑一个场景,当一个对象注册到通知中心(假设ios 8)时,中心会创建一个强对象的引用。由于< = ios8中心使对象的强引用因此保留计数增加到1。现在,苹果公司表示,我们需要删除dealloc()中的观察者以防止崩溃。我在这里没有得到两件事:如果对象是观察者并在通知中心注册,如何调用dealloc方法?

  1. 如果中心仍然保留它,如何调用object dealloc()方法?我的理解是除非保留计数为零,否则dealloc()将不会在此对象上调用。
  2. 我们假设发生了dealloc,并且我们没有移除观察者。由于对象已被释放,为什么它会崩溃?

documentation for addObserver包含以下注意事项:

如果您的应用程序的目标的iOS 9.0及更高版本或MacOS的10.11及更高版本,你不需要在它的释放方法来注销一个观察者。如果您的应用定位到早期版本,请确保在释放观察者或addObserver:selector:name:object:中指定的任何对象之前调用 removeObserver:name:object: 。

这意味着在iOS 8中,观察者被保存为unsafe_unretained参考。如果在不移除观察者的情况下解除分配观察者,则后续尝试传递通知将导致异常,因为该引用将传递给解除分配的对象。

在iOS系统9和更高版本,观察者被保持作为weak参考,与NotificationCenter试图通知观察者之前检查nil参考。如果你的目标是iOS 9或更高版本,那么你不需要明确地删除观察者。

unsafe_unretained参考号和weak参考都没有增加保留计数,所以使用NotificationCenter注册并不会阻止观察者被释放。