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.
我知道swift不允许在扩展中声明存储的属性。同样,也禁止延迟加载属性。我知道计算属性是一种替代方法,但是我的任务应该只执行一次。
Is there any hack/alternative/overlooked way to mimic lazy var in extension?
有什么方法可以在扩展中模仿lazy var吗?
Thanks!
谢谢!
2 个解决方案
#1
4
you can use computed property, combined with associatedObject. in this way, you can mimic a stored property. so the lazy var simulation will be:
您可以使用计算属性,并与associatedObject相结合。通过这种方式,您可以模拟存储的属性。因此,懒惰的var模拟将是:
// 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))
}
}
#2
7
If you don't need to refer to self
you can use a static var
:
如果不需要引用self,可以使用静态var:
extension String {
static var count = 0
static var laughingOutOut : String = {
count++
return "LOL: \(count)"
}()
}
String.laughingOutOut // outputs "LOL: 1"
String.laughingOutOut // outputs "LOL: 1"
String.laughingOutOut // outputs "LOL: 1"
(You don't need count
in your implementation; that's just there to show it's only executed once.)
(在实现中不需要计数;那只是为了显示它只执行了一次)
#1
4
you can use computed property, combined with associatedObject. in this way, you can mimic a stored property. so the lazy var simulation will be:
您可以使用计算属性,并与associatedObject相结合。通过这种方式,您可以模拟存储的属性。因此,懒惰的var模拟将是:
// 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))
}
}
#2
7
If you don't need to refer to self
you can use a static var
:
如果不需要引用self,可以使用静态var:
extension String {
static var count = 0
static var laughingOutOut : String = {
count++
return "LOL: \(count)"
}()
}
String.laughingOutOut // outputs "LOL: 1"
String.laughingOutOut // outputs "LOL: 1"
String.laughingOutOut // outputs "LOL: 1"
(You don't need count
in your implementation; that's just there to show it's only executed once.)
(在实现中不需要计数;那只是为了显示它只执行了一次)