OC 初始化器
@implementation TestView
- (instancetype)init {
NSLog(@"111 before super init");
self = [super init];
NSLog(@"111 after super init");
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
NSLog(@"111 before super initWithFrame");
self = [super initWithFrame:frame];
NSLog(@"111 after super initWithFrame");
return self;
}
@end
@implementation TestView2
- (instancetype)init {
NSLog(@"222 before super init");
self = [super init];
NSLog(@"222 after super init");
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
NSLog(@"222 before super initWithFrame");
self = [super initWithFrame:frame];
NSLog(@"222 after super initWithFrame");
return self;
}
#end
TestView2 继承自 TestView
TestView 继承自 UIView
控制器中执行 TestView2 *testView2 = [[TestView2 alloc] init];
复制代码
最后的打印结果是什么?
222 before super init
111 before super init
222 before super initWithFrame
111 before super initWithFrame
111 after super initWithFrame
222 after super initWithFrame
111 after super init
222 after super init
复制代码
为什么?
也就是说 oc 构造器执行的流程是什么?
先执行便利初始化器,并调用父类的便利初始化器,均执行完成后再从子类的指定初始化器执行依次往 上执行。
如果便利初始化器中不执行 [super init]
,指定初始化器无法被调用。
- (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
复制代码
Swift 初始化器
// 均省略了 required init?(coder: NSCoder)
class A: UIView {
convenience init() {
print("111 before convenience")
self.init(frame: CGRect.zero)
print("111 after convenience")
}
override init(frame: CGRect) {
print("111 before design")
super.init(frame: CGRect.zero)
print("111 before design")
}
}
class B: A {
convenience init() {
print("222 before convenience")
self.init(frame: CGRect.zero)
print("222 after convenience")
}
override init(frame: CGRect) {
print("222 before design")
super.init(frame: frame)
print("222 after design")
}
}
控制器中执行 B()
复制代码
执行结果如下
222 before convenience
222 before design
111 before design
111 before design
222 after design
222 after convenience
复制代码
其实 swift 的执行结果更好理解。
只是 swift 的不能乱写,否则会报错,一定要符合原则。
类类型的初始化原则(初始化器调用的原则)
- 设计初始化器必须从他的直接父类中调用一个设计初始化器。
- 便利初始化器必须从相同的类中调用另一个初始化器。
- 便利初始化器必须最终调用一个设计初始化器。
两阶段初始化(属性初始化的原则)
- 设计始化器必须保证所有类的全部属性有值,只要全部的父类属性有值,它的内存认为完全初始化了,然后进入阶段2。
- 父类的初始化器结束,子类的设计初始化器可以执行额外的自定义,之后子类的便利初始化器可以再执行额外的自定义。
继承
- 如果没有定义设计初始化器,自动继承父类的全部设计初始化器
- 如果子类重写了父类所有的设计初始化器,自动继承父类所有的便利化初始器
换而言之,如果子类只重写了父类非全部的设计初始化器,或者子类有自己的初始化器时,子类是没有相应的便利化初始化器的。
结构体
结构体的没有便利初始化器,只有设计初始化器,而且也不存在继承,所以没有上述的复杂。但是也有要注意的点:
// 下面这段代码是不会报错的
// 如果存在指定初始化器的话,那么 a 也需要给到默认值才可以。
struct T {
var a: Int
}
复制代码
参考文档:swift 官方文档
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END