2015-08-30 84 views
1

一個KVC財產我有一個自定義的NSView類中定義爲:的NSView與斯威夫特

class MyView: NSView 
{ 
    var someText: NSString 

    override func didChangeValueForKey(key: String) 
    { 
     println(key) 

     super.didChangeValueForKey(key) 
    } 

    // other stuff 
} 

我希望能夠做的就是從這個類的外部改變someText的價值,並有didChangeValueForKey通知, someText發生了變化,例如,我可以將needsDisplay設置爲true,然後執行其他一些工作。

我如何做到這一點?

回答

4

您確定您需要KVC嗎? KVC工作正常斯威夫特,但有一個簡單的方法:

var SomeText: NSString { 
    didSet { 
     // do some work every time SomeText is set 
    } 
} 
0

我會增加Jaanus的回答,爲了使KVC兼容的特性,你應該把它聲明爲dynamic var someText: NSString

但是,如果你不需要所有的花裏胡哨的KVC,didSet是要走的路。

更新

至於didChangeValueForKey: - 它是用於相反的,你通知了關鍵值已改變(如果不是由於被基金所涵蓋的情形之一)。您應該使用addObserver(_:forKeyPath:options:context:)並覆蓋observeValueForKeyPath(_:ofObject:change:context:)以通知更改。

或者您可以使用許多第三方解決方案,如ReactiveCococa的一個或Facebook的KVOController

+0

即使我將動態參數添加到someText,didChangeValueForKey方法也未被調用。如果didChangeValueForKey不是正確的方式來知道someText的值已經改變,那是什麼? – ericg

+0

對不起,沒有注意到這一部分,它確實不是正確的方法,請看我的編輯 –

1

志願和didSet不是相互排斥的:

import Foundation 
class C: NSObject { 
    dynamic var someText: String = "" { 
     didSet { 
      print("changed to \(someText)") 
     } 
    } 
} 

let c = C() 
c.someText = "hi" // prints "changed to hi" 

class Observer: NSObject { 
    init(_ c: C) { 
     super.init() 
     c.addObserver(self, forKeyPath: "someText", options: [], context: nil) 
    } 

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

let o = Observer(c) 
c.someText = "test" // prints "changed to test" and "observed change to test" 
2

沒有KVC機制,這一點,因爲這ISN」 KVC是什麼。

在Objective-C中,您將明確實現setter(或者如果該屬性最初來自超類,則重寫)並在那裏執行您的工作。

在Swift中,正確的方法是didSet機制。

didChangeValueForKey()不是KVC的一部分,它是KVO(鍵值觀測)的一部分。它不打算被覆蓋。打算在實施手動更改通知時調用它(與willChangeValueForKey()配對)。

更重要的是,沒有理由相信它將被稱爲所有的東西都沒有被觀察到的財產。 KVO調整班級,以便爲那些實際上正在觀察的屬性掛鉤設置者和其他突變訪問者。當這樣的屬性發生變化(並且支持自動更改通知)時,KVO會自動調用willChangeValueForKey()didChangeValueForKey()。但對於未觀察到的屬性,這些方法不會被調用。

最後,在某些情況下,例如索引集合突變訪問器,KVO將使用不同的更改通知方法,例如willChange(_:valuesAtIndexes:forKey:)didChange(_:valuesAtIndexes:forKey:)

如果你真的不想使用didSet出於某種原因,你會使用志願在observeValueForKeyPath(_:ofObject:change:context:)觀察selfsomeText性質的變化和處理的變化。但是,做一件簡單的事情,這是一種糟糕,笨拙,容易出錯,效率低下的方式。