支持 属性 比 Swift 中的(惰性)更安全吗?
Is backed property safer than (lazy) in Swift?
使用由另一个 属性 支持的计算 属性 是否比在 Swift 中使用 lazy
修饰符更安全?
// method 1: using LAZY variable
lazy var myVar:Int {
// assume that this calculation takes
// a lot of time and resources
return 5
}
现在考虑 Apple Swift 2(预发布)中的以下引述:
NOTE
If a property marked with the lazy
modifier is accessed by multiple
threads simultaneously and the property has not yet been initialized,
there is no guarantee that the property will be initialized only once.
就个人而言,我一直在做我自己的 "lazy" 逻辑,如下所示:
考虑替代方法:
// method 2: using calculated property backed by another property
var myVar:Int? {
if self._myVar != nil {
return self._myVar
}
let aVar:Int = 5 // assume this is done after exhaustive calcuation
self._myVar = aVar
return self._myVar
}
var _myVar:Int? = nil
使用(方法 2),我能保证 "exhaustive calculation" 只会执行一次吗?
您提出的方法 2 不能保证 lazy
不能保证的任何事情。
// method 2: using calculated property backed by another property
var myVar:Int? {
if self._myVar != nil {
return self._myVar
}
let aVar:Int = 5 // assume this is done after exhaustive calcuation
self._myVar = aVar
return self._myVar
}
var _myVar:Int? = nil
此外,它还有一个额外的缺陷,即它是可选的而不是非可选的。作为隐式解包的可选项,这会稍微好一点,所以我们不必不断地解包它。
而且,我们无法设置 myVar
。加上 _myVar
应该是私有的。
但问题是您没有锁定初始化代码以进行同步。
假设你有线程A开始访问myVar
。 if self._myVar != nil
检查 returns 为假,所以我们不会返回 self._myVar
。现在我们进入穷举计算。
现在,在穷举计算完成之前,线程 B 尝试访问 myVar
。因为线程A还没有穷举完,if self._myVar != nil
还是returnsfalse,现在线程B做穷举
本质上,这与 lazy
关键字给您带来的问题相同......但是当 lazy
就足够了时,您编写了很多代码来做到这一点。
使用由另一个 属性 支持的计算 属性 是否比在 Swift 中使用 lazy
修饰符更安全?
// method 1: using LAZY variable
lazy var myVar:Int {
// assume that this calculation takes
// a lot of time and resources
return 5
}
现在考虑 Apple Swift 2(预发布)中的以下引述:
NOTE
If a property marked with the
lazy
modifier is accessed by multiple threads simultaneously and the property has not yet been initialized, there is no guarantee that the property will be initialized only once.
就个人而言,我一直在做我自己的 "lazy" 逻辑,如下所示:
考虑替代方法:
// method 2: using calculated property backed by another property
var myVar:Int? {
if self._myVar != nil {
return self._myVar
}
let aVar:Int = 5 // assume this is done after exhaustive calcuation
self._myVar = aVar
return self._myVar
}
var _myVar:Int? = nil
使用(方法 2),我能保证 "exhaustive calculation" 只会执行一次吗?
您提出的方法 2 不能保证 lazy
不能保证的任何事情。
// method 2: using calculated property backed by another property var myVar:Int? { if self._myVar != nil { return self._myVar } let aVar:Int = 5 // assume this is done after exhaustive calcuation self._myVar = aVar return self._myVar } var _myVar:Int? = nil
此外,它还有一个额外的缺陷,即它是可选的而不是非可选的。作为隐式解包的可选项,这会稍微好一点,所以我们不必不断地解包它。
而且,我们无法设置 myVar
。加上 _myVar
应该是私有的。
但问题是您没有锁定初始化代码以进行同步。
假设你有线程A开始访问myVar
。 if self._myVar != nil
检查 returns 为假,所以我们不会返回 self._myVar
。现在我们进入穷举计算。
现在,在穷举计算完成之前,线程 B 尝试访问 myVar
。因为线程A还没有穷举完,if self._myVar != nil
还是returnsfalse,现在线程B做穷举
本质上,这与 lazy
关键字给您带来的问题相同......但是当 lazy
就足够了时,您编写了很多代码来做到这一点。