视图是应用的一个重要组成部分,功能的实现与其息息相关,而视图控制器控制着视图,其重要性在整个应用中不言而喻。
1.视图生命周期与视图控制器关系
以视图的4 种状态为基础,我们来系统了解一下视图控制器的生命周期。在视图不同的生命周期中,视图控制器会回调不同的方法,具体如图1 所示。
图1 视图控制器的一些主要方法
在视图控制器已被实例化,视图被加载到内存中时调用viewDidLoad方法,这个时候视图并未出现。在该方法中,通常进行的是对所控制的视图进行初始化处理。
视图可见前后会调用viewWillAppear:方法和viewDidAppear: 方法;视图不可见前后会调用viewWillDisappear: 方法和viewDidDisappear:方法。4个方法调用父类相应的方法以实现其功能,编码时该方法的位置可根据实际情况做以调整,参见如下代码:-(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:YES]; …… }
viewDidLoad 方法在应用运行的时候只调用一次,而这上述4 个方法可以被反复调用多次,它们的使用很广泛但同时也具有很强的技巧性。例如,有的应用会使用重力加速计,重力加速计会不断轮询设备以实时获得设备在z 轴、x 轴和y轴方向的重力加速度。不断的轮询必然会耗费大量电能进而影响电池使用寿命,我们通过利用这4个方法适时地打开或者关闭重力加速计来达到节约电能的目的。怎么使用这4 个方法才能做到“适时”是一个值得思考的问题。
在低内存情况下,iOS 会调用didReceiveMemoryWarning: 和viewDidUnload:方法。在iOS 6 之后,就不再使用viewDidUnload:,而仅支持didReceiveMemoryWarning:。didReceiveMemoryWarning: 方法的主要职能是释放内存,包括视图控制器中的一些成员变量和视图的释放。现举例如下:
- (void)didReceiveMemoryWarning { self.button = nil; self.myStringD = nil; [myStringC release]; //ARC内存管理情况下不用 [super didReceiveMemoryWarning]; }
除了上述5 个方法视图控制器外,还有很多其他方法。
2.iOS UI 状态保持和恢复
iOS 设计规范中要求,当应用退出的时候(包括被终止运行的时候),需要保持界面中UI元素的状态,当再次进来的时候看到的状态与退出时是一样的。在iOS 之后,苹果提供以下API使得UI状态保持和恢复变得很容易。
在iOS 中,我们可以在以下3种地方实现状态保持和恢复: 应用程序委托对象
视图控制器 自定义视图恢复标识是iOS 为了实现UI状态保持和恢复添加的设置项目。我们还需要在应用程序委托对象AppDelegate代码部分做一些修改,添加的代码如下:
-(BOOL) application:(UIApplication *)application shouldSaveApplicationState: (NSCoder *)coder { return YES; } -(BOOL) application:(UIApplication *)application shouldRestoreApplicationState: (NSCoder *)coder { return YES; } - (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder: (NSCoder *)coder { [coder encodeFloat:2.0 forKey:@"Version"]; } - (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder: (NSCoder *)coder { float lastVer = [coder decodeFloatForKey:@"Version"]; NSLog(@"lastVer = %f",lastVer); }
其中application:shouldSaveApplicationState:方法在应用退出时调用,负责控制是否允许保存状态,返回YES 情况是可以保存,NO是不保存。
application:shouldRestoreApplicationState:方法在应用启动时调用,负责控制是否恢复上次退出时的状态,返回YES 表示可以恢复,返回NO表示不可以恢复。 application:willEncodeRestorableStateWithCoder:方法在保存时调用,在这个方法中实现UI状态或数据的保存,其中[coder encodeFloat:2.0 forKey:@"Version"] 语句是保存简单数据。 application:didDecodeRestorableStateWithCoder:方法在恢复时调用,在这个方法中实现UI状态或数据的恢复,其中[coder decodeFloatForKey:@"Version"] 语句用于恢复上次保存的数据。 想要实现具体界面中控件的保持和恢复,还需要在它的视图控制器中添加一些代码。我们在ViewController.m中添加的代码如下:-(void)encodeRestorableStateWithCoder:(NSCoder *)coder{ [super encodeRestorableStateWithCoder:coder]; [coder encodeObject:self.txtField.text forKey:kSaveKey]; } -(void)decodeRestorableStateWithCoder:(NSCoder *)coder { [super decodeRestorableStateWithCoder:coder]; self.txtField.text = [coder decodeObjectForKey:kSaveKey]; }
在iOS 6之后,视图控制器都添加了两个方法——encodeRestorableStateWithCoder: 和decodeRestorableStateWithCoder: ,用来实现该控制器中的控件或数据的保存和恢复。其中encodeRestorableStateWithCoder:方法在保存时候调用,[coder encodeObject:self. txtField.textforKey:kSaveKey]语句是按照指定的键保存文本框的内容,decodeRestorableStateWithCoder:方法在恢复时调用,[coder decodeObjectForKey:kSaveKey]在恢复文本框内容时调用,保存和恢复事实上就是向一个归档文件中编码和解码的过程。