Swift:如何在不调用didSet函数的情况下更改属性的值

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)

War*_*ton 9

可能存在的问题是提供一个绕过你的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)

丑陋但可行

  • 很聪明 我自己会使用“ var triggerObservers = true”,以避免双重否定。 (2认同)

das*_*ght 7

你在Objective-C中做什么来"避免副作用"是访问属性的后备存储 - 它的实例变量,默认情况下以下划线为前缀(你可以使用@synthesize指令更改它).

然而,看起来Swift语言设计师特别注意使得无法访问属性的后备变量:根据书中的说法,

如果您有使用Objective-C的经验,您可能知道它提供了两种方法来存储值和引用作为类实例的一部分.除了属性之外,还可以使用实例变量作为存储在属性中的值的后备存储.

Swift将这些概念统一到一个属性声明中.Swift属性没有相应的实例变量,并且不直接访问属性的后备存储.(重点是我的)

当然,这仅适用于使用"常规语言"的意思,而不是使用反射:它可能提供一种解决这种限制的方法,但会牺牲可读性.

  • 真正.附录:如果要管理对属性"后备存储"的访问,则可以始终使用单独的私有存储属性. (6认同)