UIViewController - 查看事件生命周期并注册KVO / Notifications

时间:2013-03-13 16:23:47

标签: ios uiviewcontroller key-value-observing

我想知道在没有匹配-viewWillAppear:的情况下是否会调用-viewDidAppear:。同样适用于-viewWillDisappear-viewDidDisappear

我的问题的根源是注册和取消注册对象的KVO和/或NSNotifications的位置,更改通知将导致视图控制器更新视图。

例如,我有一个异步处理的模型对象,它的字符串属性可能会改变。我希望视图控制器能够KVO这些属性,并通过交换由所述视图控制器管理的标签的文本来反映任何更改。

您在哪里注册和取消注册通知以及原因?

修改

我遇到的问题是在应用程序状态更改的情况下应该怎么做(例如-applicationWillResignActive-...didEnterBackground等)。这些更改似乎不会触发视图控制器生命周期方法。这里有什么最好的做法吗?

2 个答案:

答案 0 :(得分:5)

使用标准容器视图控制器,您将始终成对获取将要/已做过的消息。如果您已编写自己的视图控制器容器,则可能不会,但这将是容器实现中的错误。

大多数情况下,你会想要设置内容并在' will'消息。这使得您的视图控制器能够在它变为“活跃”之前对其需要做的任何事情进行最早的拍摄。当你不再需要它们时,也会尽早关闭它们。

在导航堆栈中推送视图控制器时,完全有可能在推送动画期间发生通知。如果在viewDidAppear中设置观察者,则会错过该通知。你想尽快听。

同样,我认为viewDidDisappear为时已晚,无法删除回调。例如,可以在viewDidDisappear中停止位置管理器,但可以在消失的动画期间传递另一个位置更新。这可能不会造成太大的伤害,但根据应用程序的不同,可能会发生一些奇怪的事情,例如在您已经离开视图控制器后出现警报视图 - 这看起来像是对用户的闪烁。

如上所述,任何与视图无关的内容都会出现在' will'方法。然后,关于意志vs的选择实际上是关于用户看到的内容。动画应该在viewDidAppear中开始,否则,用户不会看到will / did期间出现的帧。数据应移动到viewWillAppear中的视图,否则,空白视图将转换,数据仅在转换动画完成后显示。此外,可以在viewWillAppear / viewDidAppear之间调整视图帧,就像堆栈中的前一个视图控制器隐藏/显示导航栏一样。

在旁注中,我不会在这里详细介绍,但我主张反对KVO进行控制器交互,将数据从模型移动到视图对象。难以测试且难以追踪。

答案 1 :(得分:0)

您可以将UILabel子类化,并在子类中覆盖setText方法:

-(void)setText:(NSString *)newText {

    //do your KVO updates here

    [super setText:newText];
}

希望这会有所帮助