一种方法是使用 KVO。特别是,将实例添加为'sButtonText
的观察者。buttonField
stringValue
更详细地说,在您的文件中,ButtonText
一旦@property IBOutlet buttonField
设置ButtonText
了NSWindowController
-windowDidLoad
ButtonText
NSViewController
-loadView
[self.buttonField addObserver:self
forKeyPath:@"stringValue"
options:0
context:&ButtonTextKVOContext];
之前在文件中定义ButtonTextKVOContext
如下:
static int ButtonTextKVOContext = 0;
然后覆盖observeValueForKeyPath:ofObject:change:context:
如下:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context != &ButtonTextKVOContext) {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
return;
}
if (object == self.buttonField) {
if ([keyPath isEqualToString:@"stringValue"]) {
NSLog(@"controlTextDidChange: %@", _buttonField.stringValue);
}
}
}
编辑
由于ButtonText
不是 or 的子类NSWindowController
,NSViewController
我们将使用稍微不同的方法。和以前一样,我们希望“一旦@property IBOutlet buttonField
设置”就开始观察。为此,将属性合成为buttonField
成员变量mButtonField
写入
@synthesize buttonField = mButtonField;
并覆盖buttonField
的设置器如下:
- (void)setButtonField:(NSTextField *)buttonField
{
[self stopObservingButtonField];
mButtonField = buttonField;
[self startObservingButtonField];
}
我们需要确保ButtonText
在释放时也停止观察按钮字段,因此覆盖-dealloc
如下:
- (void)dealloc
{
[self stopObservingButtonField];
}
仍然需要定义方法-stopObservingButtonField
和-startObservingButtonField
:
- (void)stopObservingButtonField
{
if (mButtonField) {
[mButtonField removeObserver:self
forKeyPath:@"stringValue"
context:&ButtonTextKVOContext];
}
}
- (void)startObservingButtonField
{
if (mButtonField) {
[self.buttonField addObserver:self
forKeyPath:@"stringValue"
options:0
context:&ButtonTextKVOContext];
}
}
由于这种安排,我们绝不能mButtonField
在方法之外设置变量-setButtonField:
。(这并不完全正确,但是如果我们确实设置mButtonField
了,我们必须确保首先停止观察其旧值的@"stringValue"
键路径并开始观察其新值的 @"stringValue" 键路径。这样做而不是简单地调用-setButtonField:
很可能只是构成代码重复,不值得。)
作为参考,请查看 Apple关于协议的文档NSKeyValueObserving
。