Open dannolan opened 8 years ago
Under 'Lazy Stored Properties' in Apple's 'The Swift Programming Book' there is a note that states:
"If a property marked with the lazy
modifier is accessed by multiple threads simultaneously and the property has not yet been initialised, there is no guarantee that the property will be initialised only once."
Ah darn, then my information is massively incorrect :(
Yeah, I guess there is always good ol' dispatch_once
. Sucks that isn't the default behaviour.
Actually stuff it, I'll ping Joe from the swift team and see if this is a temporary issue or something they won't fix.
— Sent from my iPhone
On Tue, Dec 1, 2015 at 9:09 PM, sboddeus notifications@github.com wrote:
Yeah, I guess there is always good ol'
dispatch_once
. Sucks that isn't the default.Reply to this email directly or view it on GitHub: https://github.com/Bilue/swift-style-guide/issues/9#issuecomment-160922975
I like this general idea, but the only way I've been able to do it safely is something like:
class AwesomeClass {
var myField: UITextField = AwesomeClass.setupCoolField()
static private func setupCoolField() -> UITextField {
return UITextField()
}
}
Double edged sword here... on one hand, it has moved the setup logic away from the definition of myField
; on the other, it offers a re-usable method that can be used to initialise multiple variables. YMMV.
In that case what do you mean by "Safe"? Because that is also not 'thread-safe'.
Why not thread-safe? The call to initialise myField
is injected into the init()
method by the compiler. If init()
method hasn't returned yet, how would another thread be able to get a reference to the object under inilitialisation? Or have I missed something?
Oops, you are completely correct. I obviously haven't had enough coffee this morning. For some reason I was still thinking about lazy vars.
I've been thrashing through this idiom recently so it's not explicitly a 'pure swift' thing but more of a good way to encapsulate logic within a particular component.
Say you have a text field and you want to perform a stack of modifications to it, you have two ways to do this
The problem being that what if myCoolFunc is called more than once, this is why you can use lazily evaluated closures on properties to guarantee they'll only be initialized once (and also they give you a convenient way to store item centric logic
IIRC lazy attributes/properties are de facto thread-safe and lazy closures are only executed ONCE meaning you get a decoupling of your property elements from your actual imperative code (if you're exclusively laying out in code). Something I've been mulling over but something I think is a good addition to the guide. Happy to discuss with others.