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 があります。アプリで SubClass を定義します。問題は、プロパティの性質についての知識なしに SubClass オブザーバーにどのように依存できるかです: それは保存されている (そしてオブザーバーに依存できる) のか、それとも計算されているのか (そして、期待するたびにオブザーバーを起動することは期待できません) ? 出来ますか?いいえの場合、カプセル化違反ですか?

4

1 に答える 1

0

その行動は完全に正常です。どのバッキング ストアが実際にどの計算プロパティに対応するかをコンパイラが知る方法はありません。この場合のバッキング ストアは、クラス自体の外ではアクセスできないプライベート変数で構成されています。したがって、「ボンネットの下」の変更が発生する可能性がある唯一の場所は、基本クラスです。計算されたプロパティ(オブザーバーをトリガーする)またはバックストア(トリガーしない)を使用するのは、そのクラスの特権です。

あなたの例では、「目に見えない」変更を決して許可したくないと仮定すると、 changeSomeValues() 関数は独自のルールに違反しており、サブクラスと呼び出し元に約束した契約を尊重していません。

于 2016-01-17T04:09:38.080 に答える