我知道swift不允许在扩展名中声明存储的属性。同样地,也禁止延迟加载的属性。我知道计算属性是另一种选择,但我所拥有的任务应该只执行一次。
是否有任何黑客/替代/被忽视的方式来模仿延伸中的懒惰变种?
谢谢!
答案 0 :(得分:7)
如果您不需要引用self
,则可以使用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"
(您在实施过程中不需要count
;只是在那里显示它只执行一次。)
答案 1 :(得分:5)
您可以使用computed属性,与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))
}
}