何时取消订阅UIView中的NSNotification

我在UIView中使用下面的NSNotifications,以便UIKeyboard出现时可以通知视图,并在屏幕上调整它的位置(框架):

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; 

上面的两个通知正在UIView的-init方法中订阅。 一旦视图从屏幕上消失,最好的地方在哪里取消订阅这些通知? 目前,当UIKeyboard出现在另一个视图中时,应用程序崩溃,大概是因为通知仍然被发送到当时发布的UIView。

另外,除了-init方法之外,还有更好的地方可以订阅通知吗?

感谢您的帮助。

即使从窗口中删除视图,也会调用-[UIView willMoveToWindow:]-[UIView didMoveToWindow] 。 在这种情况下,窗口参数(或在-didMoveToWindow情况下的窗口属性)将为零,即:

 - (void)willMoveToWindow:(UIWindow *)newWindow { if (newWindow == nil) { // Will be removed from window, similar to -viewDidUnload. // Unsubscribe from any notifications here. } } - (void)didMoveToWindow { if (self.window) { // Added to a window, similar to -viewDidLoad. // Subscribe to notifications here. } } 

除了几个边缘情况,这是一个安全的方法来做到这一点。 如果您需要更多的控制权,您可以观察视图所属窗口的隐藏属性。

我把我的removeObserver :调用放在-dealloc

到目前为止没有任何问题。

首先,您应该考虑何时停止接收通知:

  1. 当查看被释放
  2. 当视图消失时

您应该始终检查您的视图是否遵守通知,并调用-removeObserver: in -dealloc 。 另外,如果你考虑2,覆盖-viewWillDisappear-viewDidDisappear或者你操纵视图的UIViewController的视图层次的任何其他点。

我build议你将逻辑放入UIViewController,因为在关系方面UIView不拥有它的框架。

明确的答案(例如,确保NSNotificationCenter在其生命周期结束时不再引用某个对象)将按照@Tom的build议并在dealloc以观察者身份移除自己。

主观的答案是,当通知不再与对象相关时,停止观察也是一种好的做法。 这完全取决于您根据您的应用程序的devise来决定。 例如,如果您的视图保持活跃状态​​,但进入和离开视图,则可能会决定在添加到子视图时开始观察,并在删除视图时停止观察。

WRT的通知逻辑应该驻留(在视图vs控制器),这也取决于你,显然它可以同时工作。 我会根据情况做出决定。 如果在视图中处理通知需要将应用程序逻辑推入视图(即将控件视为控制器),那么这是一个红旗。

你可以创build一个单独的函数来添加和删除观察,然后你可以从视图的实例中的所有这些function。 顺便问你的问题的答案,我会删除观察员,然后从超视图中删除视图本身。 我希望你明白。

要取消订阅,您可以使用

 - (void)removeObserver:(id)notificationObserver 

要么

 - (void)removeObserver:(id)notificationObserver name:(NSString *)notificationName object:(id)notificationSender 

两种方法都是NSNotificationCenter的实例方法。

看看NSNotificationCenter类参考

作为键盘通知的做法,我通常使用

的addObserver

viewWillAppear中

removeObserver

viewWillDisAppear

每次都对我很好,它确保没有键盘通知被传递到不在屏幕上的视图,从而防止由于错误的键盘通知而使应用程序崩溃。