在我的应用程序中,我有一个对象,它通过HTTP封装了与服务器的通信。 如果服务器上有更改,此对象会使某些HTTP请求“轮询”,例如会话不再有效,或者用户有新消息,等等。
应用程序的UI对象必须将自身注册到通信对象,以通过UI对象实现的协议接收通知。注册使用如下方法完成:
[communicationObject addObserver: self];
并自行删除:
[communicationObject removeObserver: self];
通信对象将观察者存储在可变数组中。在某些情况下,UI对象是在UINavigationController中推送的UIViewControllers。在这种情况下,当用户返回到父控制器时,UI控制器没有被丢弃,因为通信对象的观察者数组保留它,并且UI控制器不能从观察者移除自己,因为 dealloc < / strong>方法永远不会被调用(显然)。
问题:这个观察者 - 通知器是一个糟糕的设计模式?有一种方法可以检测父控制器是否释放了UI控制器,而不使用 viewWillDisappear 方法?最好的做法是解决这种情况吗?
答案 0 :(得分:13)
如果您正在使用观察者模式,并且您希望视图控制器在屏幕上观察值 ,则最好在{{{{}}中调用addObserver:
1}}和viewDidAppear
中的removeObserver:
。这可不是设计或误用这些方法;实际上,这是标准做法,并且很好地利用了这些视图控制器方法。
如果您希望视图控制器继续观察值,即使在中将其从屏幕上删除,首先确保这确实是您想要的。如果是,有几件事需要记住:
viewWillDisappear
方法中,并确保在实例化和演示文稿中都调用它。setup
方法来实现,而不是在对象的生命周期中保持一致的状态。setup
。检查其视图层次结构是否就绪的好方法是通过nil
属性。这里重要的是不要混淆视图控制器(或任何对象)的想法在某处保留,并且在屏幕上 。这些是非常不同的事件,往往不一致。例如,如果您有一个“父”视图控制器(例如isViewLoaded
)管理一个或多个“子”视图控制器,则可能会有多个视图控制器同时实例化并保留,而只有一个在屏幕上一次显示。
UINavigationController
如果您愿意,另一个处理全局事件的选项是NSNotificationCenter
,它允许您指定一个NSNotificationCenter
来调用观察者,让通知匿名发布,并允许任意事件对象({{ 1}})与通知事件相关联。这样,您的selector
会将通知发布到userInfo
,您的视图控制器会在communicationObject
上观看通知。您仍然可以以类似的方式添加/删除观察者对象,但是您可以获得一种集中的,更健壮的方式来协调全局事件。