OC中经常用到的一种初始化控制器的方法.比如A push B.并且将A的一个值:value 传递给B 使用.简单的办法就是 在B重构init方法.比如在.h 中定义:
- ()initValue:(NSString *)value;
然后在.m中实现
-()initValue:(NSString *)value {
self = [super init];
if (self) {
self.value = value;
}
return self;
}
但是如果在swift中也这么写.那么就会出现问题了.
class B:UIViewController {
var param:String?
init(param: String) {
super.init()
self.param = param
}
报的错误是:
‘required‘ initializer ‘init(coder:)‘ must be provided by subclass of ‘UIViewrController‘
Super.init isn‘t called before returning from initializer
看到这个错误的时候,很迷惑.哪里错了?然后开始查找资料
1,在 Swift 中, 类的初始化器有两种, 分别是Designated Initializer(指定初始化器)和Convenience Initializer(便利初始化器)
2,如果子类没有定义任何的指定初始化器, 那么会默认继承所有来自父类的指定初始化器。
3,如果子类提供了所有父类指定初始化器的实现, 那么自动继承父类的便利初始化器
4,如果子类只实现部分父类初始化器,那么父类其他的指定初始化器和便利初始化器都不会继承。
5,子类的指定初始化器必须要调用父类合适的指定初始化器。
那么原因就很明显了.修改一下,就可以正常传值了
init(value:String){
self.value = value
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
一般来说,子类的初始化顺序是:
设置子类自己需要初始化的参数,valu = 10
调用父类的相应的初始化方法,super.init()
对父类中的需要改变的成员进行设定,name = "name"
其中第三步是根据具体情况决定的,如果我们在子类中不需要对父类的成员做出改变的话,就不存在第 3 步。而在这种情况下,Swift 会自动地对父类的对应 init 方法进行调用,也就是说,第 2 步的 super.init() 也是可以不用写的 (但是实际上还是调用的,只不过是为了简便 Swift 帮我们完成了)
如果我们不需要打改变 name 的话,
虽然我们没有显式地对 super.init() 进行调用
不过由于这是初始化的最后了,Swift 替我们自动完成了
这就是对于init传值的一种记录吧
ps:因为Swift的特性.init()方法只会调用一次.是线程安全的.