本文首发地址:http://blog.csdn.net/madongchunqiu/article/details/49702931
为了保证初始化的正确性,obj-c里面设计了Designated Initializer(指定初始化函数,下文简称DI)([1] Concepts in Objective-C Programming - Object Initialization),其目的在于保证当前class都能最终以某个函数进行初始化,从而避免部分成员变量不进行初始化的漏洞。这种做法被推荐为class设计时的best practice。swift则对DI进行了强制规定,并在编译阶段进行查错处理([2]The Swift Programming Language - Initialization)。
按照上面的设计思路,DI应该是有且只有一个才合理。然而在使用Storyboard进行设计时,我们会惊讶的发现DI并未被调用。怪!
今天详细读了文档,然后总结规律如下:
✅1. 一个class可以有多个DI ,虽然我觉得这样超极不合理。
✅2. 在“非Storyboard”情况下,UIKit class仅有一个DI。当对其进行subclass时,此DI必须被调用([3]UIView Class Reference)
✅3. 在“Storyboard”情况下,UIKit class均使用initWithCoder作为其第二个DI。当对其进行subclass时,initWithCoder必须被调用([4]View Programming Guide for iOS)
-------分割线------
因此比较常用的UIKit subclass初始化,最好提供至少两个DI,如下:
A。对UIViewController而言,override以下两个DI,并在其中调用其super的相应DI
initWithNibName:bundle:
initWithCoder:
B。对UIView而言,override以下两个DI,并在其中调用其super的相应DI
initWithFrame:
initWithCoder:
C。对UITableViewCell而言,override以下两个DI,并在其中调用其super的相应DI
initWithStyle:reuseIdentifier:
initWithCoder:
-------分割线------
如果subclass不愿使用super的DI,需要创建自己的DI的话,则遵循以下原则(详见swift programming language文档)
i)subclass新的DI,需要直接调用super的DI
ii)subclass需override其super的原DI(已成为convenience initializer)(注1),并在其中调用新的DI
iii) subclass其余的convenience initializer,均需调用新的DI
(图片来自swift programming language)
注释
注1:关于subclass设计了新的DI后,对其super的原DI的处理,在obj-c和swift中可以有不一样的处理:
obj-c中,subclass自动继承super的initializer,因此如果subclass使用了了新的DI,却不override其super的DI,则可能会出现初始化漏洞。(When you define a subclass, you must be able to identify the designated initializer of the superclass and invoke it in your subclass’s designated initializer through a message to super. You must also make sure that inherited initializers are covered in some way. 摘自([1]Concepts in Objective-C Programming - Object Initialization))
swift中,subclass不会自动继承super的initializer,因此可以不考虑这个问题。(Unlike subclasses in Objective-C, Swift subclasses do not inherit their superclass initializers by default. 摘自([2]The Swift Programming Language - Initialization))
参考
[1] Concepts in Objective-C Programming - Object Initialization, https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/Initialization/Initialization.html
[2] The Swift Programming Language - Initialization, https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html
[3] UIView Class Reference, https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/
[4] View Programming Guide for iOS, https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html