3

Swift 2.2でこれが可能かどうか疑問に思っています、計算されたプロパティのKVO!Swiftの計算されたプロパティのKVO

すなわち:

var width = 0 
    var height = 0 

    private var area : Double { 
      get { 
       return with * height 
      } 
    } 

    self.addOberser(self, forKeyPath: "area", ...... 

だろうとか、高トリガーobserveValueForKeyPathを変更するクライアントコード?

市長クラスのリファクタリングを行う前に確認してください。誰かが手元に答えがあるなら、KVOの構文はそれほど厄介なものです(答えはNOと仮定しています)

は〜D

+0

KVOがあなたのセッター@dhomesあるセッター、すべてについて期待何をすべきと思いますか? –

+1

['RxSwift'](https://github.com/ReactiveX/RxSwift)をご覧ください。 – dfri

+0

@Basheer_CADこれがポイントです!私は1つは読み取り専用の計算されたプロパティを観察することができますか?幅または高さを設定して新しい面積の計算をトリガーしますか? (いいえ、と思うだろうが、おそらくいくつかの派手なコンパイラ?) –

答えて

9

このコードは、2つの理由のために動作しません。“Adopting Cocoa Design Patterns” in Using Swift with Cocoa and Objective-C下の「キー値観測」で説明したように

  1. あなたは、areaプロパティにdynamic属性を追加する必要があります。

  2. あなたは“Registering Dependent Keys” in the Key-Value Observing Programming Guideで説明したようにareawidthheightに依存していることを宣言しなければなりません。 (これはObjective-CとSwiftにも当てはまります)。これが機能するには、widthheightdynamicを追加する必要があります。

    (あなたは代わりにwillChangeValueForKeydidChangeValueForKeyたびwidthまたはheight変更を呼び出すことができますが、それはただkeyPathsForValuesAffectingAreaを実装するために、通常は簡単です。)したがって

class MyObject: NSObject { 

    dynamic var width: Double = 0 
    dynamic var height: Double = 0 

    dynamic private var area: Double { 
     return width * height 
    } 

    class func keyPathsForValuesAffectingArea() -> Set<String> { 
     return [ "width", "height" ] 
    } 

    func register() { 
     self.addObserver(self, forKeyPath: "area", options: [ .Old, .New ], context: nil) 
    } 

    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { 
     print("observed \(keyPath) \(change)") 
    } 

} 

let object = MyObject() 
object.register() 
object.width = 20 
object.height = 5 

出力:

observed Optional("area") Optional(["old": 0, "new": 0, "kind": 1]) 
observed Optional("area") Optional(["old": 0, "new": 100, "kind": 1]) 
+1

私はこれらの同じドキュメンテーションのリンクに従って、あなたはコンテキストを指定することになっていると思いますか? – MarqueIV

+1

通常、いくつかの理由で 'context'を使うのは良い考えですが、この答えはKVOのその部分に関するものではありません。また、 'NSObject'を継承するだけであれば、' NSObject'はKVO通知を登録しないので、あなたが望む以外は 'context'を使う必要はないので、あなたのスーパークラスと競合する可能性はありません。 –

+0

良い情報!共有ありがとう! – MarqueIV

1

@Robが彼の答えで述べたように、areadynamic今すぐ両方の性質のためにwillSet内、widthheightプロパティの
willSet { }didSet { }を追加Objective-Cの

から観察されるように作るこのself.willChangeValueForKey("area") を追加し、didSetself.didChangeValueForKey("area");を追加

ここで、areaのオブザーバは、幅または高さが変更されるたびに通知されます。

注:このコードはテストされていませんが、私はそれが

関連する問題