Sunday, 15 March 2015

ios - How to properly implement lazy instantiation with an @IBOutlet property in Swift -



ios - How to properly implement lazy instantiation with an @IBOutlet property in Swift -

i learning ios development big nerd ranch's latest ios book. have chosen implement apps in swift. in 1 of apps, have next code in objective c:

- (uiview *)headerview { // if have not loaded header view yet... if (!_headerview) { // load headerview.xib [[nsbundle mainbundle] loadnibnamed:@"headerview" owner:self options:nil] } homecoming _headerview; }

apple's swift guide on "@iboutlet":

when declare outlet in swift, compiler automatically converts type weak implicitly unwrapped optional , assigns initial value of nil. in effect, compiler replaces @iboutlet var name: type @iboutlet weak var name: type! = nil.

as pointed out in lazy loading properties in swift, there couple of different options. none of them in post explicitly mention lazy initialization @iboutlet, i've done best implement suggestions, , know considered best practices.

attempt #1(failed): next similar pattern, illustration appdelegate.swift. brings issue "'iboutlet' attribute requires property mutable"

@iboutlet var headerview : uiview { // if headerview has not been loaded yet... if !_headerview { // load headerview.xib nsbundle.mainbundle().loadnibnamed("headerview", owner: self, options: nil) } homecoming _headerview! } var _headerview : uiview? = nil

attempt #2(failed): using variation of "@lazy" "@iboutlet" didn't worked because "@lazy" needs initializer, if closure used, "@iboutlet" has same issue effort #1

attempt #3(successful?): way able work. got thought different question, lazy property initialization in swift. understanding of happening headerview declared "@iboutlet weak var headerview : uiview! = nil", initialized 1 time tableviewcontroller subclass have, , initialization "lazy" in occurs when tableviewcontroller needs loaded.

@iboutlet var headerview : uiview func loadheaderview() { // if headerview has not been loaded yet... if !headerview { // load headerview.xib println("loaded headerview") nsbundle.mainbundle().loadnibnamed("headerview", owner: self, options: nil) } } override func viewdidload() { super.viewdidload() loadheaderview() tableview.tableheaderview = headerview }

so, how can improved?

is viewdidload() right function use?

thanks

you aren't providing closure headerview code, you're declaring read-only computed property. @iboutlet properties need mutable xib/storyboard can magic, you'd need implement both getter , setter, this:

@iboutlet var headerview : uiview { { if !_headerview { nsbundle.mainbundle().loadnibnamed("headerview", owner: self, options: nil) } homecoming _headerview! } set { _headerview = newvalue } } var _headerview : uiview? = nil

ios objective-c cocoa-touch swift

1 comment: