Swift中required init(coder:)代码提取为方法的问题咨询
问题原因及解决方法
核心原因:Swift初始化阶段的安全规则限制
你遇到的问题是违反了Swift类初始化的核心安全规则:在调用父类初始化器super.init(coder:)之前,不能调用任何实例方法。
在你最初的代码中,是直接在init(coder:)里给selectedFocusAreas赋值,这属于对当前类存储属性的直接初始化操作,是Swift允许的。但当你把初始化逻辑提取到setUpSelectedFocusAreaData()这个实例方法后,在super.init之前调用它就不行了——因为此时你的ViewController实例还没有完成初始化,实例方法可能依赖于未完全初始化的属性或实例状态,编译器会直接阻止这种不安全的操作。
另外补充一点:如果focusAreas是当前类的存储属性,在super.init之前访问它其实也需要确保它已经被初始化(比如是默认值或者在init里提前赋值了),你的原始代码能编译说明它满足这个条件,但调用实例方法的限制是硬性的。
两种可行的解决方法
方法1:把实例方法调用移到super.init之后
这是最直接的修正方式,因为调用super.init后,父类初始化完成,当前实例也进入了安全状态,可以正常调用实例方法:
required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder)! setUpSelectedFocusAreaData() } func setUpSelectedFocusAreaData(){ selectedFocusAreas = [] for _ in 0...focusAreas.count { selectedFocusAreas.append(false) } // 或者用更简洁的写法替代循环: // selectedFocusAreas = Array(repeating: false, count: focusAreas.count + 1) }
方法2:将初始化逻辑改为静态方法(如果不需要访问实例状态)
如果setUpSelectedFocusAreaData的逻辑只依赖传入的参数(比如focusAreas.count),不依赖其他实例属性,可以把它改成静态方法,这样就能在super.init之前调用,直接给selectedFocusAreas赋值:
required init(coder aDecoder: NSCoder) { selectedFocusAreas = Self.setUpSelectedFocusAreaData(focusAreasCount: focusAreas.count) super.init(coder: aDecoder)! } static func setUpSelectedFocusAreaData(focusAreasCount: Int) -> [Bool] { return Array(repeating: false, count: focusAreasCount + 1) }
内容的提问来源于stack exchange,提问作者user481610
相关产品推荐
相关产品推荐

