swift的构造过程是两段式的,什么是两段式呢,就是类实例的初始化,即构造器的调用和执行过程,分为两个阶段。
先来看两个阶段是怎么个分法,弄清楚两个阶段分别做了什么,就自然明白为什么要分两个阶段以及这么做的好处了。
首先来看两个图,图片来自《TheSwiftProgrammingLanguage》:
这是swift的继承链,Convenience表示遍历构造器,Designated表示指定构造器,右图可以看出:
这个构造链只是表示了继承关系,并没有详细给出构造过程,以下两张图片详细表示了构造过程的两个阶段:
第一阶段:
第二阶段:
从图中可以看到,第一阶段是自下而上的,而第二阶段是自上而下的,怎么理解呢?
明确这一点后,再看一个原则:
一个对象的内存只有在其所有的存储属性全部确定之后才能完全初始化。
也就是说,我们在指定构造器中对类的存储属性初始化,必须完成自身引入的存储属性和继承自父类的存储属性这两类属性的初始化后,实例才完全初始化,如果在构造器中只初始化自身引入的存储属性,或者只初始化继承自父类的存储属性,该实例都无法完成初始化。
所以,我们初始化一个实例通常不仅要为自身引入的属性赋初值,还要调用父类的构造方法来处理父类的属性,这样每个类都对自身引入的属性初始化后,调用父类的构造方法,一层一层调用上去,最终到达了继承链顶端,实例才真正完成初始化。
在swift中,上述过程严格执行安全检查,以确保构造过程顺利完成,其第一阶段的任务就是,完成实例的完全初始化,而第二阶段的任务则是,可以由我们对已经完全初始化好的实例进行进一步的定制。
简单来说就是:
第二阶段自上而下,从继承链顶端开始向下,给了我们在每一层对实例进行再定制的权利,我们可以在这个过程中在任意一层对实例进行修改。
反映在代码上:
需要明确的是,这么做并不是因为这样的流程更加清晰,而是swift严格要求必须按照这样的顺序,下面就是swift为了保证两段式构造过程顺利完成而进行的四个安全检查:
从第四条可以看出,只有在第一阶段完成之后,实例才真正初始化完成。
两个阶段的详细过程解读如下: