Swift 类的初始化器

本节主要以class的初始化器讲解,struct 的初始化器与class类似,但不完全相同,而且不会牵扯到继承的问题;

口诀

  • 便捷实现靠自身,必要实现靠super,指定实现看需要

介绍

  • 类初始化时会调用的代码块,必须在此处完成 未初始化的 非可选类型的 存储属性的赋值操作;
  • 使用init关键字修饰,注意是关键字;

分类

  • 指定初始化器:可以有多个,如果是基类则自动实现init(){},否则是继承父类的,也可重写父类的。
  • 便捷初始化器:可以有多个,使用convenience修饰,不能继承重写父类的,实现中必须调用自身的指定初始化器。eg: self.init()
  • 必要初始化器:可以有多个,使用required修饰。

使用注意事项

  • 指定初始化器:super只能调用父类的指定初始化器,不可调用超类的。以HJViewController为例:
init() {
   // 不允许这样写
    super.init()
}
//所以以下写法可以,但同样‘不建议’这样写 init() 与超类同名了
init() {
     super.init(nibName: nil, bundle: nil)
}
  • 便捷初始化器:如果自定义了指定初始化器,则父类的指定初始化器就不能在便捷初始化器中使用。最好不要与所有父类(超类)的初始化器重名,会导致父类(超类)的方法不被调用,还有可能造成循环调用。以HJViewController为例:
convenience init() {
    self.init(nibName: nil, bundle: nil)
}
  • 必要初始化器:有以下几点
    1. 如果父类实现必要初始化器,而子类没有实现(自定义/重写父类)指定初始化器必要初始化器,则自动继承,反之则必须实现。

    2. 基于1. 实现中可不必调用 父类/自身 的指定初始化器。eg:

required init?(coder: NSCoder) {
    //一般调用super ,亦可自己实现。此示例是因为`HJViewController`父类遵守了NSCoding协议
    //super.init(coder: coder)
}
  1. 如果自身增加必要初始化器,实现中只能调用父类的指定初始化器。eg: super.init()

作为最终使用的类,在UIViewController中使用的建议

指定初始化器最好只有一个 或者没有
不建议UIViewController的子类重写父类指定初始化器,或自定义指定初始化器,因为这样做必须要实现required init?(coder: NSCoder)此‘必要初始化器
建议使用convenience修饰初始化器:这种初始化器称为便捷初始化器;便捷初始化器内部必须调用一个指定初始化器。
如果非要在初始化时做点什么的话,如果func viewDidLoad()不满足,则只能重写下边这个触发条件中提到的指定初始化器

触发条件

  • 外部调用OC:[[HJViewController alloc]init],[[HJViewController alloc]initWithNibName:nil bundle:nil]
  • 外部调用Swift:HJViewController(),HJViewController(nibName: nil, bundle: nil)
  • 都会走以下指定初始化器
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
   // self.datas = [1] 未调用父类的指定初始化器 此时对象未初始化完成 self不可用
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init?(coder: NSCoder) {
    super.init(coder: coder)
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容