Is it possible to allow didSet to be called during initialization in Swift?
Create an own set-Method and use it within your init-Method:
class SomeClass {
var someProperty: AnyObject! {
didSet {
//do some Stuff
}
}
init(someProperty: AnyObject) {
setSomeProperty(someProperty)
}
func setSomeProperty(newValue:AnyObject) {
self.someProperty = newValue
}
}
By declaring
someProperty
as type:AnyObject!
(an implicitly unwrapped optional), you allow self to fully initialize withoutsomeProperty
being set. When you callsetSomeProperty(someProperty)
you're calling an equivalent ofself.setSomeProperty(someProperty)
. Normally you wouldn't be able to do this because self hasn't been fully initialized. SincesomeProperty
doesn't require initialization and you are calling a method dependent on self, Swift leaves the initialization context and didSet will run.
If you use defer
inside of an initializer, for updating any optional properties or further updating non-optional properties that you've already initialized and after you've called any super.init()
methods, then your willSet
, didSet
, etc. will be called. I find this to be more convenient than implementing separate methods that you have to keep track of calling in the right places.
For example:
public class MyNewType: NSObject {
public var myRequiredField:Int
public var myOptionalField:Float? {
willSet {
if let newValue = newValue {
print("I'm going to change to \(newValue)")
}
}
didSet {
if let myOptionalField = self.myOptionalField {
print("Now I'm \(myOptionalField)")
}
}
}
override public init() {
self.myRequiredField = 1
super.init()
// Non-defered
self.myOptionalField = 6.28
// Defered
defer {
self.myOptionalField = 3.14
}
}
}
Will yield:
I'm going to change to 3.14
Now I'm 3.14