扩展中的延迟加载属性(Swift)
Posted
技术标签:
【中文标题】扩展中的延迟加载属性(Swift)【英文标题】:Lazy loading property in Extension (Swift) 【发布时间】:2015-03-23 03:58:32 【问题描述】:我知道 swift 不允许在扩展中声明存储的属性。同样的道理,延迟加载的属性也是被禁止的。我知道计算属性是一种替代方法,但我的任务应该只执行一次。
在扩展中是否有任何 hack/替代/被忽略的方法来模仿惰性 var?
谢谢!
【问题讨论】:
最好的做法可能是使用您将创建的变量的返回类型为函数 【参考方案1】:如果您不需要参考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
;这只是为了表明它只执行一次。)
【讨论】:
无论我创建多少个实例,静态变量laughingOutOut
占用的内存都是一个单独的字符串来保存LOL: \(count)
。这就是静态工作。我说的对吗?【参考方案2】:
你可以使用计算属性,结合关联对象。通过这种方式,您可以模仿存储的属性。所以惰性 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))
【讨论】:
感谢您的回答。有必要使用这种方法吗?如果我只检查#varname# 是否不为零,它会不会给出相同的结果?类似var hi:String = get if let hi = hi return hi else // init hi
。谢谢!
你需要一个地方来存储财产的价值。计算属性只是封装了 getter 和 setter 方法。它没有存储变量的地方。和 associatedObject 提供了这样一个地方。 associatedObject 还将确保对象在不需要时得到释放。就像一个真正的存储属性。如果你在 getter 方法中使用计算属性,我认为这将是一个递归循环,并且会用完堆栈。以上是关于扩展中的延迟加载属性(Swift)的主要内容,如果未能解决你的问题,请参考以下文章