在Swift中对象的初始化方法分为两种,指定构造器(Designated Initializers)和便利构造器(Convenience Initializers)。记录一下我对它的初步理解。swift
其实就是OC的init初始化方法。OC中通常初始化某个类(以Person为例,属性有name和age),使用以init开头的方法,以下:安全
在.h中暴露出声明方法。
//默认name="",age=0
- (instancetype)init;
//以name来初始化,默认age=0
- (instancetype)initWithName:(NSString *)name;
//赋值name和age来初始化
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age;
复制代码
实现方法以下:bash
在.m中写方法实现。
// 便利构造器
- (instancetype)init {
return [self initWithName:@""];
}
// 便利构造器
- (instancetype)initWithName:(NSString *)name {
return [self initWithName:name age:0];
}
// 指定构造器
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age {
self = [super init];
if (!self) {
return nil;
}
_name = name;
_age = age;
return self;
}
复制代码
而Swif中的三种也是这样,init()以下。这里我在ide
.swift中写方法
//此处,我给name和age初始值。
var name: String = ""
var age: Int = 0
// 便利构造器
override convenience init() {
self.init(name: "haha")//此处默认名字是haha,是为了方便看出子类可继承convenience init方法。
}
// 便利构造器
convenience init(name: String) {
self.init(name: name, age:0)
}
// 指定构造器
init(name: String, age: Int) {
super.init()
self.name = name
self.age = age
}
复制代码
写Swift这段代码时,有以下问题函数
注意:Swift不一样于OC的init,它没有返回值。在这一过程里面初始全部的存储属性和其它的必要初始化操做。 ui
存储属性,在调用任何方法(好比子类调父类的super.init,或者调本类的方法)以前,都应该确保在本类对存储属性进行初始化。若是name和age并无给初始值,则代码应该改为以下,以init(name: String, age: Int)为例:spa
init(name: String, age: Int) {
self.name = name
self.age = age
super.init()
}
复制代码
这是因为Swift的内存安全,在调用父类构造方法以前,确保对本类的全部存储属性进行初始化。采用了Two-Phase Initialization(两段式构造)模型来实现内存安全。code
Github源码文档有一处是三段式构造,第三段:若是还有其它操做,可执行其它方法来完成初始化。对象
指定构造器,这是一个类最主要的方法,若是有父类,则子类的指定构造器方法必需要调父类的指定构造方法与父类关联。好比上面的Swift的Person类,继承
init(name: String) {
super.init()
self.name = name
}
复制代码
便利构造器,便捷生成实例的方法,对指定构造器的参数作了选择,可不用传那么多参数。
class Boy: Person {
var girlFriendName: String
override init(name: String, age: Int) {
self.girlFriendName = "girl"
super.init(name: name, age: age)
print("我完成了init")
}
}
复制代码
若是Person里面还有另外一个指定构造方法,则Boy类里面也须要重写此方法。不然调用Boy.init()会报错。调用Boy.init()的构造过程以下: