I have a class, with say 100 properties (exaggeration). Most of these properties must be computed, based off of user preferences.
These properties will not change after the initialization, which is why I would like to run the computations once at the beginning, and set the results into let
properties
Users can set tens of preferences, and depending on the combination of preferences set, the properties here will change when I initialize an object.
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
}
You get the point, at this point my init
will be hundreds of lines long, basically unreadable.
I would like to separate these chunks of logic out into separate methods, something like:
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
}
This way the init
is much more readible, and it should be easier to debug and maintain.
The issue is that obviously the compiler won't be happy that my init
method is not explicitly initializing these properties, and I get something akin to:
'self' used before all stored properties are initialized
and also, inside of computeAndSetProp1()
, I will get this error:
cannot assign to property: 'prop1' is a 'let' constant
Is there a way to split up this large init?
You can make the computeAndSetProp1()
function be a free function (that is, not part of any class), like this:
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.
}
}
I'd also recommend seeing if you can generalize the computeAndSetProp*
functions to reduce the amount of code. You can always post the code on Code Review to get more ideas about how to simplify the code.