0

据我所知,Swift 允许我们为存储和计算属性设置属性观察器。但是如果计算的属性值依赖于一些后备存储,当这些后备存储值发生更改时,不会触发属性观察器:

public class BaseClass {
    private var privateVar1: Int = 0
    private var privateVar2: Int = 0
    public var property: Int {
        get {
            return privateVar1 * privateVar2
        }
        set {
            print("some setter without effect")
        }
    }
    private func changeSomeValues() {
        privateVar1 = 1
        privateVar2 = 2
    } 
}

public class SubClass : BaseClass {
    override var property: Int {
        didSet {
            print("didSet \(property)")
        }
    }
}

调用 changeSomeValues 时不调用 SubClass 的 didSet。

让我们考虑一个案例:我们在第三方框架中有这样的 BaseClass。我们在我们的应用程序中定义子类。问题是:我们如何在不了解属性性质的情况下依赖子类观察者:它是存储的(我们可以依赖观察者)还是计算的(然后我们不能期望每次都在我们期望的时候触发观察者)?可能吗?如果不是,是否违反封装?

4

1 回答 1

0

这种行为是完全正常的。编译器无法知道哪个后备存储真正对应于哪个计算属性。在这种情况下,您的后备存储由私有变量组成,这些变量在类本身之外无法访问。因此,唯一可能发生“幕后”变化的地方是基类。使用其计算属性(将触发观察者)或后备存储(不会触发)是该类的特权。

在您的示例中,假设您永远不想允许“不可见”的更改,则 changeSomeValues() 函数违反了自己的规则,并且不尊重它向其子类和调用者承诺的合同。

于 2016-01-17T04:09:38.080 回答