知识卡片

两段式构造保证实例不会带着半初始化状态被访问

专业/工作 · 721

内容

类的构造过程分两个阶段:第一阶段从最底层子类的指定构造函数开始,先确保本类新引入的存储属性全部有值,再向上代理给父类的指定构造函数做同样的事,一路到最顶层父类,这时整个实例的内存才算真正完全初始化;第二阶段再反过来从顶层父类往下,每一层构造函数才被允许访问 self、调用实例方法、进一步定制属性。编译器据此做强制检查:本类属性没赋完值不准向上代理父类构造、代理父类之前不准动 self。这套顺序把”实例的任何一部分内存处于未初始化状态”这件事在构造阶段就彻底堵死,比很多语言里”构造函数里能不能调用虚方法”这种容易踩坑的灰色地带要严格得多。便利构造函数(convenience init)不直接初始化属性,只能横向调用同类的其他构造函数、最终落到某个指定构造函数上,是这套体系里”给常见场景提供快捷方式”的角色,不参与两段式流程本身的安全责任。

参考来源

《Swift全解析:新式iOS实战开发》第15章《Swift初始化》