Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Friday, March 18, 2016

Is it possible to allow didSet to be called during initialization in Swift?

Is it possible to allow didSet to be called during initialization in Swift?


Question

Apple's docs specify that:

willSet and didSet observers are not called when a property is first initialized. They are only called when the property?s value is set outside of an initialization context.

Is it possible to force these to be called during initialization?

Why?

Let's say I have this class

class SomeClass {      var someProperty: AnyObject {      didSet {          doStuff()      }      }        init(someProperty: AnyObject) {          self.someProperty = someProperty          doStuff()      }        func doStuff() {          // do stuff now that someProperty is set      }  }  

I created the method doStuff, to make the processing calls more concise, but I'd rather just process the property within the didSet function. Is there a way to force this to call during initialization?

Update

I decided to just remove the convenience intializer for my class and force you to set the property after initialization. This allows me to know didSet will always be called. I haven't decided if this is better overall, but it suits my situation well.

Answer by Oliver for 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      }  }  

Answer by Charlesism for Is it possible to allow didSet to be called during initialization in Swift?


As a variation of Oliver's answer, you could wrap the lines in a closure. Eg:

class SomeClass {        var someProperty: AnyObject! = nil {          didSet {              // Do something          }      }        init( someProperty: AnyObject ) {            // Closure to invoke didSet()          { self.someProperty = someProperty }()        }    }  

If your closure is multiple lines, you can wrap it in parens: ({ self.someProperty = someProperty })()

Answer by yshilov for Is it possible to allow didSet to be called during initialization in Swift?


You can solve it in obj-? way:

class SomeClass {      private var _someProperty: AnyObject!      var someProperty: AnyObject{          get{              return _someProperty          }          set{              _someProperty = newValue              doStuff()          }      }      init(someProperty: AnyObject) {          self.someProperty = someProperty          doStuff()      }        func doStuff() {          // do stuff now that someProperty is set      }  }  

Answer by Brian Westphal for Is it possible to allow didSet to be called during initialization in Swift?


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  

Answer by moby for Is it possible to allow didSet to be called during initialization in Swift?


While this isn't a solution, an alternative way of going about it would be using a class constructor:

class SomeClass {      var someProperty: AnyObject {      didSet {          // do stuff      }      }        class func createInstance(someProperty: AnyObject) -> SomeClass {          let instance = SomeClass()           instance.someProperty = someProperty          return instance      }    }  


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.