为视图添加函数参数后,现有计算属性初始化触发报错
问题原因分析
这个报错的核心是Swift严格的初始化顺序规则,和你新增的action存储属性直接相关:
Swift初始化的核心要求
对于自定义类(比如你继承UIView的视图),必须遵守两个关键顺序规则:- 先初始化当前类的所有存储属性,才能调用父类的
super.init - 在当前类所有存储属性初始化完成、且调用
super.init之前,绝对不能访问self(包括访问self的任何属性,不管是存储属性还是计算属性)
- 先初始化当前类的所有存储属性,才能调用父类的
新增
action后的问题点
你新增的action是没有默认值的存储属性,必须在初始化器里显式赋值。而你的代码顺序大概率是:- 先执行了
self.desc = desc(不管desc是计算属性还是存储属性,这一步都会隐式访问self) - 之后才去初始化
self.action = action
这就违反了规则:此时action还没初始化,当前类的存储属性没有全部完成初始化,却提前访问了self,所以触发报错。
- 先执行了
为什么之前没问题?
没加action的时候,你的视图类要么没有自定义的存储属性,要么所有存储属性都有默认值(编译器会自动帮你完成初始化)。这时候你可以直接调用super.init,之后再操作desc,自然不会触发初始化顺序的错误。
修复方案
调整初始化器的代码顺序即可:
// 正确顺序: init(frame: CGRect, action: @escaping () -> Void) { // 1. 先初始化当前类的所有存储属性 self.action = action // 2. 调用父类初始化方法 super.init(frame: frame) // 3. 最后再访问/设置self的属性(包括计算属性desc) self.desc = desc }
如果desc是存储属性且有默认值,也可以在初始化存储属性之后、super.init之前设置,但必须确保所有存储属性都已初始化:
init(frame: CGRect, action: @escaping () -> Void) { self.action = action self.desc = "自定义描述" // 此时action已初始化,所有存储属性完成,可安全访问self super.init(frame: frame) }
内容的提问来源于stack exchange,提问作者Subcreation
相关产品推荐
相关产品推荐

