如果服务器上有更改,如会话不再有效,或者用户有新消息,则此对象会使一些HTTP请求“轮询”.
应用程序的UI对象必须向通信对象注册自己,以通过UI对象实现的协议接收通知.注册是用以下方法完成的:
[communicationObject addObserver: self];
并自行删除:
[communicationObject removeObserver: self];
通信对象将观察者存储在可变数组中.在某些情况下,UI对象是被UINavigationController推送的UIViewControllers.在这种情况下,当用户返回到父控制器时,UI控制器不被配置,因为通信对象的观察者数组保留它,并且UI控制器不能从观察者中移除自身,因为dealloc方法从未被调用(明显).
问题:这个观察者通知是不好的设计模式?有一种方法来检测UI控制器是否由父控制器发布,而不使用viewWillDisappear方法?有最好的做法来解决这种情况吗?
解决方法
如果您正在使用观察者模式,并且希望视图控制器仅在屏幕上观察值时,最好在viewDidAppear和removeObserver:viewWillDisappear中调用addObserver:.这是不好的设计或滥用这些方法的;实际上,这是标准实践,并且非常好地利用了这些视图控制器的方法.
如果你想要一个视图控制器继续观察一个值,即使它从屏幕上删除,首先要确保这是真正你想要的.如果是,有几件事要记住:
>特别是,请确保您的视图控制器设置为如果先前存在,并且将其新进入屏幕时将具有相同的状态,就好像从头开始实例化并立即将其传送到屏幕.一个很好的方法(通常我在自己的项目中做的)是将所有设置代码保存在一个安装方法中,并确保它在实例化和呈现中都被调用.
>另外,一定要避免在后台引起昂贵的无关计算.通常,这可以通过依靠在呈现视图控制器时调用的设置方法来实现,而不是为对象的寿命保持一致的状态.
>最后,请务必记住,视图控制器在屏幕上仅具有连接(视图/子视图,通常统称为视图层次结构).当它是关闭,但保留,这些都是零.检查其视图层次结构是否准备好的好方法是通过isViewLoaded属性.
保留v.演示
重要的是在这里不要混淆视图控制器(或任何对象,为此)被保留在某个地方的想法,它在屏幕上.这些是非常不同的事件,往往不重合.例如,如果您有一个管理一个或多个“子”视图控制器的“父级”视图控制器(如UINavigationController),则可能会同时实例化和保留多个视图控制器,而屏幕上仅显示一个视图控制器一次
更好:NSNotificationCenter
如果您愿意,另一个处理全局事件的选项是通过NSNotificationCenter,它允许您指定一个选择器来调用观察者,让匿名发布通知,并允许任意事件对象(userInfo)与通知事件相关联.通过这种方式,您的CommunicationObject将向[NSNotificationCenter defaultCenter]发布通知,您的视图控制器将会在defaultCenter上观察到通知.您仍然可以以类似的方式添加/删除观察者对象,但您可以获得一种集中式,更强大的协调全局事件的方式.