在折腾NSKeyedUnarchiver期间,需要搞懂:
if let gMsgTVCDictObj = NSKeyedUnarchiver.unarchiveObjectWithFile(savedFilePath){ |
和
override func viewDidLoad() { super.viewDidLoad() |
之前的先后顺序,逻辑关系。
swift NSKeyedUnarchiver viewDidLoad
ios – SWIFT – Property not seen outside viewdidload – Stack Overflow
iOS Essentials: The UIViewController Lifecycle | Roadfire Software
FlappySwift/GameViewController.swift at master · fullstackio/FlappySwift
NSKeyedArchiver breaking a Swift object
[总结]
init(coder:)
只会被调用一次
init类型的函数,都只是会被执行到一次
对于另外还有其它类型的init函数的时候,
比如:
init()
init(xxx:YYY)
之类的,
注:
此处指所以有:
init(coder:)
这个初始化函数,是因为:
UIViewController实现了Protocol协议NSCoding
该协议,才存在所谓的coder,主要指的是:
会被(从Storyboard或文件)解码而恢复出来的视图控制器
至少有两种可能:
- 从故事版Storyboard:从界面设计时Xcode中的设计InterfaceBuilder中设计好的界面,此处自动从Storyboard中找到对应的视图控制器,并加载出来
- 从NSKeyedUnarchiver(的unarchiveObjectWithFile):把之前存储的文件数据解码成对应的视图控制器实例
此处的init函数被调用,意味着:
有可能,但不是完全一定,将来的某个时刻,你的视图控制器,可能会(被加载到内存中后再去)显示出来
换句话说:
视图控制器,虽然被init了,但是也肯能一直没机会显示的
所以:
init函数中,只初始化那些必要的变量就可以了
更多的,更复杂的初始化,不要放在init
留到之后(可能会被调用到)的viewDidLoad或viewWillAppear,会更合适
那些必要的变量的初始化,包括:
类的本身自己的变量
一些其它一些依赖的东西,包括:一些子视图subview
-》viewDidLoad()
当视图控制器被加载到内存中时,会被调用,且只会被调用一次
此处,去做一些必要的事情,那些你之前在
用Storyboard中不方便做的事情
比如一些通过代码添加的额外的对于视图自动布局相关的约束条件等等
注意:
viewDidLoad之后,未必一定会被立即显示,即未必马上就会调用到viewWillAppear
因为在视图被加载到内容中之后,视图未必就一定会被后来的操作去调用显示出来
当然,当用户操作到对应的界面时,需要显示的时候,后续会调用到viewWillAppear的
但是viewDidLoad只会被调用一次
加载到内容中之后,即可。
-》viewWillAppear(_:)
后被多次调用:
只要视图将要显示,就会被调用
可能的原因有:
- 用户点击了会退按钮
- 关闭了弹出的窗口后
- 切换tab
-》viewWillDisappear(_:)
类似于viewWillAppear,同样会被调用多次
只要视图从屏幕上消失,不显示,都会被调用
比如:
- 屏幕内容消失
- 切换到别的tab
- 点击按钮而显示一个弹窗性质的窗口
- 通过导航栏继续切换到别的视图
以上几个函数中,都需要调用到对应的super父一级的函数,去确保父一级的内容能够先正确的初始化,即:
required init?(coder aDecoder: NSCoder){ //init self related values super.init(coder: aDecoder) } override func viewDidLoad() { super.viewDidLoad() } override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) } override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) } |