I know that swift doesn't allow declaring stored property within extension. And by the same token, lazily loaded properties are also prohibited. I know computed property is an alternative, but the task I have should only be executed once.
Is there any hack/alternative/overlooked way to mimic lazy var in extension?
Thanks!
To lazily initialize a property in Swift you add the lazy keyword: Note that lazy properties are always declared with var. The closure is called when the property is accessed which can be after initialization completes.
Lazy Properties in Swift Swift language allows you to create several different types of properties, including computed, property observers and even lazy properties. In this article, we will learn how lazy properties can provide performance benefits for time consuming calculations. Implementation
A lazy var is a property whose initial value is not calculated until the first time it’s called. It’s part of a family of properties in which we have constant properties, computed properties, and mutable properties. A lazy property might be lesser known to beginners in Swift but are actually super valuable once you know when and how to use them.
This is actually a great example of a situation where you should use a computed property. As you can see, now the BMI index is always correct whether you change the weight / height or not. The original example demonstrates how to use lazy variables in Swift. However, in this case, it makes sense to use a computed property instead.
If you don't need to refer to self
you can use a static var
:
extension String {
static var count = 0
static var laughingOutLoud : String = {
count++
return "LOL: \(count)"
}()
}
String.laughingOutLoud // outputs "LOL: 1"
String.laughingOutLoud // outputs "LOL: 1"
String.laughingOutLoud // outputs "LOL: 1"
(You don't need count
in your implementation; that's just there to show it's only executed once.)
you can use computed property, combined with associatedObject. in this way, you can mimic a stored property. so the lazy var simulation will be:
// global var's address used as key
var #PropertyKey# : UInt8 = 0
var #varName# : #type# {
get {
if let v = objc_getAssociatedObject(self, & #PropertyKey#) as #type# {
return v
}else {
// the val not exist, init it and set it. then return it
// this way doesn't support nil option value.
// if you need nil option value, you need another associatedObject to indicate this situation.
}
}
set {
objc_setAssociatedObject(self, & #PropertyKey#, newValue, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With