NSNotificationCenter的removeObserver:方法是否可以取消视图控制器接收内存警告通知?

12
我在我的应用程序中遇到了一个问题:我测试了对包括viewDidUnloadUIViewController进行的didReceiveMemoryWarning调用。
这在我应用程序的旧版本中运行良好,但现在在iPhone模拟器中没有工作: didReceiveMemoryWarning不再被调用。
这是因为在viewWillDisappear中调用了[NSNotificationCenter defaultCenter] removeObserver:self](其中self是UIViewController),以注销我在viewDidAppear中添加的某些生命周期通知。
全局的removeObserver:调用不仅删除了我添加的通知,而且显然也删除了系统的UIApplicationDidReceiveMemoryWarningNotification通知,导致UIViewController的didReceiveMemoryWarning被调用。
这是设计行为吗?我找不到任何参考/文档,指出在UIViewController内调用removeObserver:会破坏标准的memoryWarning处理。
2个回答

16

是的,这是有意设计的。

这种行为并不让我感到惊讶。UIViewController的实现是不透明的,因此无法确定它是否正在使用didReceiveMemoryWarning动作向UIApplicationDidReceiveMemoryWarningNotification注册实例,但这肯定是有道理的。

通常情况下,除了在dealloc中之外,在任何地方使用[[NSNotificationCenter defaultCenter] removeObserver:self]都是一个糟糕的做法。这是因为,正如您发现的那样,在超类实现中可能会出现不可预测的副作用。如果你遵循仅取消注册你注册的特定通知的惯例,你的代码更容易预测和调试/维护。


顺便说一句,我希望苹果提供一种注销某些选择器的方法,因为这样做出错的可能性要小得多(除非您已经重写了选择器,在这种情况下它已经出错了)。 - tc.
@tc 我会认为,如果Apple-Code注册了一个事件,很可能这个类提供了一个匹配的方法来覆盖(例如_didRecieveMemoryWarning_)。文档中提供一些提示会更好。注销_selectors_可以使事情更加可控。 - marcus

4

[NSNotificationCenter defaultCenter] removeObserver:observer]会注销observer之前注册的所有通知(包括系统通知)。您可以使用removeObserver:name:object:方法取消订阅单个通知。


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