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 aftersuper.init
-> swift compiler gives error uninitialized variablemyimageview
before callingsuper.init
- calling
func commoninit()
beforesuper.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
Post a Comment