2015-08-30 39 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性质的变化和处理的变化。但是,做一件简单的事情,这是一种糟糕,笨拙,容易出错,效率低下的方式。