首页 » iOS编程(第4版) » iOS编程(第4版)全文在线阅读

《iOS编程(第4版)》24.3 恢复标识和恢复类

关灯直达底部

系统在保存应用状态时,首先会查询UIWindow对象rootViewController的restorationIdentifier(恢复标识)属性,如果rootViewController具有restorationIdentifier属性,那么系统会保存其状态;然后,系统会遍历rootViewController的子视图控制器,并保存它们的状态;接下来继续遍历这些视图控制器的子视图控制器……直到层次结构的最后一级。如果其中某个视图控制器没有restorationIdentifier属性,那么系统不会保存该视图控制器及其所有子孙视图控制器的状态,无论子孙视图控制器是否具有restorationIdentifier属性。

例如,在图24-2中,应用有两个用灰色标识的视图控制器,它们没有恢复标识,因此系统无法恢复其状态,也无法恢复其子视图控制器的状态。

图24-2 恢复标识

根据Apple命名规范,通常应该将类名作为类的恢复标识。打开BNRAppDelegate.m,在application:didFinishLaunchingWithOptions:中为UINavigationController对象设置恢复标识:

- (BOOL)application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

self.window = [[UIWindow alloc]

initWithFrame:UIScreen.mainScreen.bounds]];

BNRItemsViewController *itemsViewController =

[[BNRItemsViewController alloc] init];

// 创建一个UINavigationController对象,

// 其根视图控制器是itemsViewController

UINavigationController *navController = [[UINavigationController alloc]

initWithRootViewController:itemsViewController];

// 将UINavigationController对象的类名设置为恢复标识

navController.restorationIdentifier =

NSStringFromClass([navController class]);

// 将UINavigationController对象设置为UIWindow的rootViewController

self.window.rootViewController = navController;

self.window.backgroundColor = [UIColor whiteColor];

[self.window makeKeyAndVisible];

return YES;

}

现在UINavigationController对象已经有了恢复标识,系统会保存该对象的状态,同时,如果该对象的子孙视图控制器有恢复标识,系统也会保存它们的状态。

对于BNRItemsViewController和BNRDetailViewController,应该在指定初始化方法中设置其恢复标识。除此之外,还需要为两个视图控制器设置恢复类(restoration class)。系统在恢复某个对象的状态时,会要求其恢复类创建该对象。

打开BNRItemsViewController.m,修改init方法,设置恢复标识和恢复类:

- (instancetype)init

{

// 调用父类的指定初始化方法

self = [super initWithStyle:UITableViewStylePlain];

if (self) {

UINavigationItem *navItem = self.navigationItem;

navItem.title = @“Homepwner”;

self.restorationIdentifier = NSStringFromClass([self class]);

self.restorationClass = [self class];

对于BNRDetailViewController,则应该在initForNewItem:方法中设置:

- (instancetype)initForNewItem:(BOOL)isNew

{

self = [super initWithNibName:nil bundle:nil];

if (self) {

self.restorationIdentifier = NSStringFromClass([self class]);

self.restorationClass = [self class];

if (isNew) {

最后,还要为添加BNRItem对象时以模态形式推入的UINavigationController对象设置恢复标识。

重新打开BNRItemsViewController.m,修改addNewItem:方法,代码如下:

- (IBAction)addNewItem:(id)sender

{

// 通过BNRItemStore单例创建一个新的BNRItem对象

BNRItem *newItem = [[BNRItemStore sharedStore] createItem];

BNRDetailViewController *detailViewController =

[[BNRDetailViewController alloc] initForNewItem:YES];

detailViewController.item = newItem;

detailViewController.dismissBlock = ^{

[self.tableView reloadData];

};

UINavigationController *navController = [[UINavigationController alloc]

initWithRootViewController:detailViewController];

navController.restorationIdentifier =

NSStringFromClass([navController class]);

(请注意,以上代码并没有为两个UINavigationController对象设置恢复类,它们将由应用程序委托负责创建,下一节会介绍相关过程。)

现在,Homepwner中所有视图控制器都已经具有了恢复标识,当应用进入后台运行或被终止时,系统会保存所有视图控制器的状态。