1、当控件不是从 xib、storyboard 中创建时会调用initWithFrame方法
2、当控件是从xib、storyboard中创建时会调用initWithCoder,awakeFromNib
注意:你的view或cell在xib或storyboard上有体现,比如直接用xib创建的,或是拉
控件关联已有类等。而且,即使我们自定义的view是纯代码,没有xib,但
我们在vc的xib里引用了,效果是一样的。只要我们有在xib或storyboard里
引用过,就都会执行initWithCoder和awakeFromNib。执行顺
initWithCoder -> awakeFromNib
特别说明:如果您从nib文件中装载定制视图类的实例,则需要知道:在iPhone OS中,装载nib的代码并不通过initWithFrame:方法来实例化新的视图对象,而是通过NSCoding协议定义的initWithCoder:方法来进行。
即使您的视图采纳了NSCoding协议,Interface Builder也不知道它的定制属性,因此不知道如何将那些属性编码到nib文件中。所以,当您从nib文件装载定制视图时,initWithCoder:方法不具有进行正确初始化所需要的信息。为了解决这个问题,您可以在自己的类中实现awakeFromNib方法,特别用于从nib文件装载的定制类。
当控件从xib或storyboard中加载的时候,情况就变得复杂了,首先我们知道有initWithCoder方法,该方法会在对象被反序列化的时候调用,,一般是在xib或storyboard中写一个View,然后让系统来完成反序列化的工作,此时在initWithCoder调用之后,awakeFromNib方法也会被执行,既然在awakeFromNib方法里也能做初始化操作,那我们如何抉择?
一般来说要尽量在initWithCoder中做初始化操作,毕竟这是最合理的地方,只要你的控件支持序列化,那么它就能在任何被反序列化的时候执行初始化操作,这里适合做全局数据、状态的初始化工作,也适合手动添加子视图。
awakeFromNib相较于initWithCoder的优势是:当awakeFromNib执行的时候,各种IBOutlet也都连接好了;而initWithCoder调用的时候,虽然子视图已经被添加到视图层级中,但是还没有引用。如果你是基于xib或storyboard创建的控件,那么你可能需要对IBOutlet连接的子控件进行初始化工作,这种情况下,你只能在awakeFromNib里进行处理。同时xib或storyboard对灵活性是有打折的,因为它们创建的代码无法被继承,所以当你选择用xib或storyboard来实现一个控件的时候,你已经不需要对灵活性有很高的要求了,唯一要做的是要保证用户一定是通过xib创建的此控件,否则可能是一个空的视图,可以在initWithFrame里放置一个断言或者异常来通知控件的用户。