ctp*_*ose 20 properties swift didset
如何在Swift中设置属性的值,而不didSet()在初始化上下文之外调用它的函数?下面的代码是在类noside()函数中实现此目的的失败实验
class Test
{
var toggle : Bool = 0
var hoodwink : Int = 0 {
didSet(hoodwink)
{
toggle = !toggle
}
}
// failed attempt to set without a side effect
func noside(newValue : Int)
{
hoodwink = newValue
println("hoodwink: \(hoodwink) state: \(toggle)")
}
func withside(newValue : Int)
{
self.hoodwink = newValue
println("hoodwink: \(hoodwink) state: \(toggle)")
}
}
Run Code Online (Sandbox Code Playgroud)
使用自动合成属性在Objective-C中进行操作非常简单:
有副作用(如果存在于setter中):
self.hoodwink = newValue;
Run Code Online (Sandbox Code Playgroud)
没有副作用:
_hoodwink = newValue;
Run Code Online (Sandbox Code Playgroud)
可能存在的问题是提供一个绕过你的didSet的setter
var dontTriggerObservers:Bool = false
var selectedIndexPath:NSIndexPath? {
didSet {
if(dontTriggerObservers == false){
//blah blah things to do
}
}
}
var primitiveSetSelectedIndexPath:NSIndexPath? {
didSet(indexPath) {
dontTriggerObservers = true
selectedIndexPath = indexPath
dontTriggerObservers = false
}
}
Run Code Online (Sandbox Code Playgroud)
丑陋但可行
你在Objective-C中做什么来"避免副作用"是访问属性的后备存储 - 它的实例变量,默认情况下以下划线为前缀(你可以使用@synthesize指令更改它).
然而,看起来Swift语言设计师特别注意使得无法访问属性的后备变量:根据书中的说法,
如果您有使用Objective-C的经验,您可能知道它提供了两种方法来存储值和引用作为类实例的一部分.除了属性之外,还可以使用实例变量作为存储在属性中的值的后备存储.
Swift将这些概念统一到一个属性声明中.Swift属性没有相应的实例变量,并且不直接访问属性的后备存储.(重点是我的)
当然,这仅适用于使用"常规语言"的意思,而不是使用反射:它可能提供一种解决这种限制的方法,但会牺牲可读性.