ios - How to implement two inits with same content without code duplication in Swift? -


assume class derived uiview follows:

class myview: uiview {     var myimageview: uiimageview      init(frame: cgrect) {         super.init(frame: frame)     }      init(coder adecoder: nscoder!) {         super.init(coder: adecoder)     }      ... 

if wanted have same code in both of initializers, like

self.myimageview = uiimageview(frame: cgrectzero) self.myimageview.contentmode = uiviewcontentmode.scaleaspectfill 

and not duplicate code twice in class implementation, how structure init methods?

tried approaches:

  • created method func commoninit() called after super.init -> swift compiler gives error uninitialized variable myimageview before calling super.init
  • calling func commoninit() before super.init fails self-evidently compiler error "'self' used before super.init call"

i had same problem.

as gozoner said, marking variables optional work. it's not elegant way because have unwrap value each time want access it.

i file enhancement request apple, maybe "beforeinit" method called before every init can assign variables don't have use optional vars.

until then, put assignments commoninit method called dedicated initialisers. e.g.:

class gradientview: uiview {     var gradientlayer: cagradientlayer?  // marked optional, not have assigned before super.init      func commoninit() {         gradientlayer = cagradientlayer()         gradientlayer!.frame = self.bounds         // more setup      }      init(coder adecoder: nscoder!)  {         super.init(coder: adecoder)         commoninit()     }       init(frame: cgrect) {         super.init(frame: frame)         commoninit()     }      override func layoutsubviews() {         super.layoutsubviews()         gradientlayer!.frame = self.bounds  // unwrap explicitly because var marked optional     } } 

thanks david had @ book again , found might helpful our deduplication efforts without having use optional variable hack. 1 can use closure initialize variable.

setting default property value closure or function

if stored property’s default value requires customization or setup, can use closure or global function provide customized default value property. whenever new instance of type property belongs initialized, closure or function called, , return value assigned property’s default value. these kinds of closures or functions typically create temporary value of same type property, tailor value represent desired initial state, , return temporary value used property’s default value.

here’s skeleton outline of how closure can used provide default property value:

class someclass { let someproperty: sometype = {     // create default value someproperty inside closure     // somevalue must of same type sometype     return somevalue     }()  } 

note closure’s end curly brace followed empty pair of parentheses. tells swift execute closure immediately. if omit these parentheses, trying assign closure property, , not return value of closure.

note

if use closure initialize property, remember rest of instance has not yet been initialized @ point closure executed. means cannot access other property values within closure, if properties have default values. cannot use implicit self property, or call of instance’s methods.

excerpt from: apple inc. “the swift programming language.” ibooks. https://itun.es/de/jeuh0.l

this way use on, because not circumvent useful feature of not allowing nil on variables. example it'll this:

class gradientview: uiview {     var gradientlayer: cagradientlayer = {         return cagradientlayer()     }()      func commoninit() {         gradientlayer.frame = self.bounds         /* more setup */     }      init(coder adecoder: nscoder!)  {         super.init(coder: adecoder)         commoninit()     }      init(frame: cgrect) {         super.init(frame: frame)         commoninit()     } } 

Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

ios - Change Storyboard View using Seague -