两种构造器
Swift中为确保类在创建时每个属性都会被初始化,定义了两种构造器,分别为指定构造器(designated initializer)和便利构造器(convenience initializer),每一个类都要至少包含一个指定构造器,而两种构造器之间的调用要符合以下三条规则:
规则1
指定构造器必须调用其直接父类的指定构造器
规则2
便利构造器必须调用同一类中定义的其它构造器
规则3
便利构造器必须最终以调用一个指定构造器结束
即:指定构造器必须向上代理
便利构造器必须横向代理
关系如下图所示:
初始化的两个阶段(两段式构造过程)
Swift中类的构造包含两个阶段。简单来说,就是要保证属性先初始化,然后才能对属性进行操作。具体来讲就是:
阶段一
- 一个类的指定或便利初始化器需被调用
- 类的实例的内存被申请,但还没有初始化
- 指定初始化器确保当前类引入的所有储存属性都初始化
- 指定初始化器调用其父类的指定初始化器,继续让父类去初始化它所引入的储存属性
- 上面这个过程一直进行直到最终的根类的指定初始化器被调用
- 当根类的指定初始化器调用后,该类的实例就已经确保了所有储存属性都已经初始化完成,阶段一完成。
阶段二
- 步骤二是从根类的指定初始化器开始的,一层层到最终的子类的指定初始化器
- 在这个步骤中,每个类都有机会对已经步骤一中初始化完成的实例再次进行自定义修改。此时初始化器已经可以访问 self,修改属性或者调用实例方法了。
构造器的继承和重载
Swift中子类默认并不会自动继承父类的init方法,除非是给新加属性一个默认值,这种情况下才会自动继承父类init方法。有以下规则:
规则一:
如果你的子类没有定义任何指定初始化器,则其会自动继承其父类的所有指定初始化器
规则二:
如果你的子类实现了其父类的所有指定初始化器,不管是自定义的实现还是因为规则一造成的实现,该子类自动继承其父类所有的便利初始化器。
需要注意的是,如果在子类定义了自己的指定构造器,那么将不会继承任何父类的构造方法了,如果想继承,需要用override修饰