关于UI状态恢复过程


概述

图一阐明了从app加载到恢复完成为止这期间的函数调用顺序。恢复过程发生在app初始化过程中期,但仅当app代理对象的application:shouldRestoreApplicationState:函数返回YES时,这个过程才能被开启。

Figure 1 The interface restoration sequence

d

恢复过程的第一步是为界面创建view controller对象(显示或者隐式的创建);第二步是解码和恢复这些对象的状态。而重建view controller层级体系需要在这两步中来完成。例如,创建完一个navigation controller和它的child view controllers后,它们之间并没有立即被关联起来。更确切地,我们需要在navigation controller的 decodeRestorableStateWithCoder:函数中去重建它与它的 child view controllers之间的关系。

状态恢复完成后,UIKit调用app代理对象的application:didFinishLaunchingWithOptions:方法。可以在这个方法中对界面做最后的调整和补充。比如,你可以在view controller 层级中添加一个登陆窗口。

重建View Controller

恢复过程中,UIKit会尝试创建或从界面中寻找view controller对象。UIKit首先会让你来提供view controller对象。如果你没有提供,UIKit将进行隐式查找。下面是UIKit重建View Controller的流程。

  1. 从View Controller的restoration class中获取。一个restoration class知道如何创建一个特定的View Controller对象。你可以通过给View Controller的restorationClass属性赋值来指定restoration class。恢复过程中,UIKit会调用restoration class的viewControllerWithRestorationIdentifierPath:coder:方法来请求返回某个view controller的新的实例。如果返回nil,那么UIKit会停止尝试创建这个view controller的实例子对象,并将其从恢复进程中移出。

  2. 从app delegate方法中获取。如果View controller没有 restoration class,UIKit调用app delegate的application:viewControllerWithRestorationIdentifierPath:coder:方法;如果返回nil,UIKit会继续进行下面的检查流程。

  3. 查找已经存在的对象。UIKit查找是否有已经创建的拥有同一恢复路径的view controller

  4. 从storyboard中实例化view controller对象。如果仍然没有 view controller对象,UIKit会自动地从storyboards实例化它。

状态恢复开始之前,UIKit从storyboards中加载一些默认的的view controllers。因为UIKit自动加载这些view controller,所以最好不要从restoration class 或者 app delegate去创建它们。对于其他view controller,当且仅当某个view controller没有在storyboad中定义时,才去考虑给restorationClass属性赋值。在某些特定场景中,赋值restoration class的目的也许时为了阻止view controller的创建;例如,如果恢复过程中,发现数据解码失败或者数据比较陈旧(不兼容当前版本),也许你会决定不显示这个view controller。

当在代码中重新创建view controller时,总是需要对view controller的restorationIdentifier 属性重新赋值并进行其它初始化操作。适当的时候,也同样需要对restorationClass属性赋值。在创建的时候对这些属性赋值,以确保在下一轮循环中(app生命周期)能保存它们的状态。

func viewController(withRestorationIdentifierPath 
                    identifierComponents: [Any], 
                    coder: NSCoder) -> UIViewController? {
   let vc = MyViewController()

   vc.restorationIdentifier = identifierComponents.last as? String
   vc.restorationClass = MyViewController.self

   return vc
}

Note

你的restoration class应该总是返回UIKit期望的类型。恢复归档器中包含了每一个被保存状态的view controller的类型。如果你的restoration class返回一个不同类型的view controller实例,UIKit不会调用这个view controller对象的decodeRestorableStateWithCoder:方法。

参考:About the UI Restoration Process

知识共享许可协议本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
本站文章除注明转载/出处外,均为本站原创或翻译,请务必在遵守许可协议的前提下转载。
发布时间:2019-07-11 13:09:49 阅读:147 标签:技术翻译iOS