向/从NSNotificationCenter添加/移除观察者的最佳实践

3
什么是向/从NSNotificationCenter添加和删除观察者的最佳实践?
我想知道在viewDidLoad中将self作为观察者添加,然后在viewDidUnload中删除self是否足够。或者也许我应该在dealloc中删除self
也许需要考虑低内存条件。我可以看到在viewDidLoad中添加并在dealloc中删除可能存在问题:由于内存不足而调用了viewDidUnload...然后当视图再次显示时调用了viewDidLoad...现在self已经被添加为观察者两次而没有被删除(因为dealloc没有被调用)。
注意:我只考虑一个基本示例,其中self指的是UIViewController子类。
2个回答

8

我通常在viewWillAppear中注册UIViewController观察者,并在viewWillDisappear中移除它们。

viewWillDisappear对我来说似乎比viewWillUnload更安全,因为后者方法只会在iOS版本低于5.0的情况下出现低内存情况才调用。

最合适的答案可能取决于您的视图控制器正在做什么。您是否希望在显示视图之前就能够接收到(并需要对其做出反应)通知?如果是这样,也许在viewDidLoad中添加观察者是正确的选择。


有趣。那么在iOS 5+中,在低内存情况下会调用什么来代替viewDidUnload? - SundayMonday
1
在低内存条件下,“didReceiveMemoryWarning”会持续被调用。此外,请查看苹果的UIViewController(特别是其中的“内存管理”部分):当发生低内存警告时,如果UIViewController类知道它可以稍后重新加载或重新创建视图,则会清除其视图。如果发生这种情况,它还会调用viewDidUnload方法,以便让您的代码有机会放弃与视图层次结构相关联的任何对象的所有权。 - Michael Dautermann

8

对于 iOS 9+ 和 OS X 10.11+,在WWDC 2015 session 202 "What's New in Cocoa"中宣布:

NSNotificationCenter
自动注销已释放的观察者

let center = NSNotificationCenter.defaultCenter()
center.addObserver(self,
                   selector: "localeChanged:",
                   name: NSCurrentLocaleDidChangeNotification,
                   object: nil)

无需调用

let center = NSNotificationCenter.defaultCenter()
center.removeObserver(self,
                      name: NSCurrentLocaleDidChangeNotification,
                      object: nil)

请查看:视频在33:27,pdf幻灯片241页。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接