我有一堂课,说100个属性(夸张)。 这些属性中的大多数必须根据用户的偏好进行计算。
这些属性在初始化后将不会更改,这就是为什么我想一开始就运行一次计算并将结果设置为let
属性的原因
用户可以设置数十个首选项,并且根据设置的首选项组合,当我初始化对象时,此处的属性将更改。
let prop1:String
let prop2:String
...
let prop100:String
init(maybeRelevantArg:Int, maybeRelevantArg2:String) {
var proposedProp1 = ""
//20 lines of logic to compute proposedProp1, referencing preferences and maybeRelevantArgs
self.prop1 = proposedProp1
var proposedProp2 = ""
//20 lines of logic to compute proposedProp2, referencing preferences and maybeRelevantArgs
self.prop2 = proposedProp2
}
您明白了,在这一点上,我的init
长了几百行,基本上是不可读的。
我想将这些逻辑块分成单独的方法,例如:
init(maybeRelevantArg:Int, maybeRelevantArg2:String) {
self.computeAndSetProp1(relevantArg:maybeRelevantArg1)
self.computeAndSetProp2(relevantArg:maybeRelevantArg2)
}
func computeAndSetProp1(relevantArg:String) {
var proposedProp1 = ""
//20 lines of logic to compute proposedProp1, referencing preferences and relevantArgs
self.prop1 = proposedProp1
}
通过这种方式,init
更具可读性,并且应该更容易调试和维护。
问题是,显然我的init
方法没有显式初始化这些属性,编译器对此不满意,而我得到的类似于:
在所有存储属性初始化之前使用的“ self”
,而且在computeAndSetProp1()
内,我将收到此错误:
无法分配给属性:“ prop1”是一个“ let”常量
有没有办法拆分这个大的init?
答案 0 :(得分:1)
您可以将computeAndSetProp1()
函数设为自由函数(即,不属于任何类),如下所示:
func computeAndSetProp1(relevantArg: String) -> String {
var proposedProp1 = ""
//20 lines of logic to compute proposedProp1, referencing preferences and relevantArgs
return proposedProp1;
}
class someClass: NSObject {
let prop1 : String
let prop2 : String
override init() {
prop1 = computeAndSetProp1(relevantArg: "x")
//...etc.
}
}
我还建议您查看是否可以泛化computeAndSetProp*
函数以减少代码量。您随时可以将代码发布在Code Review上,以获取有关如何简化代码的更多想法。
答案 1 :(得分:0)
一种方法是将init参数存储在private let属性中,并将计算结果存储在已计算的var中。如果您希望计算逻辑只发生一次,也可以使用一个私有(设置)的惰性变量。
其他想法可能是将类分为具有相关属性的多个类/结构,然后使现有的类保留这些较小的类/结构。