Swift编程:存储属性中的getter/setter

boh*_*anl 102 ios swift

如何在Swift中覆盖存储属性的setter?

在Obj-C中,我可以覆盖它的setter,但是Swift对于getter/setter用于存储属性似乎并不高兴.

假设我有一个Card叫做属性的类rank.我不希望客户端给它任何无效值,因此,在objective-C中,我可以覆盖setRank它以便执行额外的检查.但是willSet在Swift中似乎没有帮助,因为newValue它是常量而且分配是没有意义的,rank因为setter将在循环中被调用.

Mih*_*atu 107

好.通过Swift上的Apples文档阅读我发现了这个:

如果为其自己的didSet观察者中的属性赋值,则分配的新值将替换刚刚设置的值.

所以你要做的就是:

var rank: Int = 0 {
    didSet {
        // Say 1000 is not good for you and 999 is the maximum you want to be stored there
        if rank >= 1000  {
            rank = 999
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 奇迹般有效!注意在init()中设置属性时不会调用它 (2认同)

Jos*_*ark 35

您不能覆盖get/ set存储属性,但可以使用属性observers willSet/ didSet:

var totalSteps: Int = 0 {
    willSet(newTotalSteps) {
        println("About to set totalSteps to \(newTotalSteps)")
    }
    didSet {
        if totalSteps > oldValue  {
            println("Added \(totalSteps - oldValue) steps")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

默认参数名称是newValuefor willSetoldValuefor didSet,或者您可以自己命名,如willSet(newTotalSteps).

  • 我不完全确定你的意思,但你不能使用`didSet`来检查`rank`后它被设置,如果验证失败,重置为其他东西,例如`oldValue`? (2认同)

Jim*_*oll 9

如果您不想使用didSet,它具有属性的值暂时错误的问题,您应该围绕它包装计算属性.

private var _foo:Int = 0
var foo:Int {
    get {
        return _foo
    }
    set {
        if(newValue > 999) {
            _foo = 999
        } else {
            _foo = newValue
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

要么:

private var _foo:Int = 0
var foo:Int {
    get {
        return _foo
    }
    set {
        guard newValue <= 999 else {
            _foo = 999
            return
        }
        _foo = newValue
    }
}
Run Code Online (Sandbox Code Playgroud)


use*_*131 8

get和set用于计算属性(它们没有任何后备存储).(在我看来,关键字'var'在这里令人困惑)

  • 为实例变量调用willSet和didSet(使用didSet覆盖任何更改)
  • set和get纯粹用于计算属性