init简介
iOS中init
一个对象时,会调用对象的init
方法,进入init
方法时会调用initWithNibName
方法,可调试验证
每个ios开发者对loadView
和viewDidLoad
肯定都很熟悉,虽然这两个函数使用上真的是非常简单,但是和类似的initWithNibName
/awakeFromNib
/initWithCoder
放在一起还是非常容易让人混淆的.
一、loadView
永远不要主动调用这个函数。view controller
会在view
的property
被请求并且当前view
值为nil
时调用这个函数。如果你手动创建view
,你应该重载这个函数。如果你用IB
创建view
并初始化view controller
,那就意味着你使用initWithNibName:bundle:
方法,这时,你不应该重载loadView
函数。
这个方法的默认实现是这样:先寻找有关可用的nib
文件的信息,根据这个信息来加载nib
文件,如果没有有关nib
文件的信息,默认实现会创建一个空白的UIView
对象,然后让这个对象成为controller
的主view
。
所以,重载这个函数时,你也应该这么做。并把子类的view
赋给view
属性(property
)(你create
的view
必须是唯一的实例,并且不被其他任何controller
共享),而且你重载的这个函数不应该调用super
。
如果你要进行进一步初始化你的views
,你应该在viewDidLoad
函数中去做。在iOS 3.0以及更高版本中,你应该重载viewDidUnload
函数来释放任何对view的引用或者它里面的内容(子view
等等)。
二、viewDidLoad
这个函数在controller
加载了相关的views
后被调用,而不论这些views
存储在nib
文件里还是在loadView
函数中生成。而多数情况下是做nib
文件的后续工作。
三、viewDidUnload
这个函数是viewDidLoad
的对立函数。在程序内存欠缺时,这个函数被controller
调用,来释放它的view
以及view
相关的对象。由于controller
通常保存这view
以及相关object
的引用,所以你必须使用这个函数来放弃这些对象的所有权以便内存回收。但不要释放那些难以重建的数据。
通常controller
会保存nib
文件建立的views
的引用,但是也可能会保存着loadView
函数创建的对象的引用。最完美的方法是使用合成器方法:
self.myCertainView = nil;
这样合成器会release
这个view
,如果你没有使用property
,那么你得自己显示释放这个view
。
网上对这个函数的描述含含糊糊,看了等于没看。
四、结论
所以流程应该是这样:
(loadView/nib
文件)来加载view
到内存 ——>viewDidLoad
函数进一步初始化这些view
——>内存不足时,调用viewDidUnload
函数释放views
——>当需要使用view
时又回到第一步
如此循环
需要厘清两个概念,创建一个类和实例化一个类.在XCode
中创建一个类和实例化一个类很容易区分,但是在IB(Interface Builder)
中有时候就会迷糊.其实也很好区分,孤零零地创建了一个nib
文件,没有和其他可被实例化的类有直接或间接关系的时候,这个类或这些类(一个nib
文件俺也可能包含多个类)是没有机会被实例化的,所以这种情况只是通过IB
创建了一个类,而没有实例化.真正的实例化还需要通过在Xcode
用代码来读取这个nib
文件.知道这两这的区别后这些方法也就容易辨认多了
viewDidLoad
其实没什么可混淆的,无论通过什么途径加载(Xcode
或者IB
,这里的加载属于实例化)完view
后肯定会执行这个方法.
loadView
需要分两种情况.当你通过Xcode
实例化一个类的时候就需要自己在controller
中实现这个方法.而在IB
中实例化就不需要实现它.
initWithNibName
这个方法是在controller
的类在IB
中创建,但是通过Xcode
实例化controller
的时候用的.
awakeFromNib
这个方法是一个类在IB
中被实例化时被调用的.看了帖子发现大家都推荐使用viewDidLoad
而不要使用awakeFromNib
,应为viewDidLoad
会被多次调用,而awakeFromNib
只会当从nib
文件中unarchive
的时候才会被调用一次.实际测试中发现,当一个类的awakeFromNib
被调用的时候,那么这个类的viewDidLoad
就不会被调用了,这个感觉很奇怪.
initWithCoder
是一个类在IB
中创建但在xcode
中被实例化时被调用的.比如,通过IB创建一个controller
的nib
文件,然后在xocde
中通过initWithNibName
来实例化这个controller
,那么这个controller
的initWithCoder
会被调用.
awakeFromNib
当.nib
文件被加载的时候,会发送一个awakeFromNib
的消息到.nib
文件中的每个对象,每个对象都可以定义自己的awakeFromNib
函数来响应这个消息,执行一些必要的操作。也就是说通过nib
文件创建view
对象是执行awakeFromNib
viewDidLoad
当view
对象被加载到内存是就会执行viewDidLoad
,所以不管通过nib
文件还是代码的方式创建对象都会执行viewDidLoad