有没有人知道如何阻止Cocoa绑定将值设置回绑定属性但仍会触发默认操作选择器?
我正在尝试将NSTextField绑定到我的数据对象上的只读NSString属性。 我的数据对象就像
...
@property(readonly)NSString * outCome;
- (无效)otherMethodsAffectOutCome;
...
我将NSTextField绑定到results属性,并在默认操作处理程序中调用-otherMethodAffectOutCome,我希望/ didChangeValueForKey可以触发outCome属性的观察者并返回NSTextField。
但它不起作用,NSTextField会崩溃,因为它试图通过setOutCome方法设置更改后的文本...我想我需要NSTextField监视属性值更改,但不要尝试在文本更改时设置值,我该怎么做?
谢谢! -Jonny
答案 0 :(得分:1)
由于您已拥有自己的模型对象,因此有两个选项比覆盖-setValue:forUndefinedKey:
更好。
只需将属性更改为readonly
即可。由于它是Objective-C对象,因此应该retain
编辑。
如果您需要将该属性公开为readonly
外部世界,您可以仅在实施中手动定义setOutCome:
;对于外面的世界来说,看起来这个属性是只读的,除非有一些智者出现并直接调用-setOutCome:
。其中一个明智之处是Cocoa Bindings技术本身。
这是一个坏主意,除非你非常了解retain
setter应该如何工作以及你是否非常小心。此外,您必须将该属性转换为nonatomic
- iOS上的建议设置,但不能转换为OS X.
最后,这里是这三个的最佳解决方案,方法2的变体。除了“类别”,类也可以有“扩展”。简单地解释一下,您应该将这些视为非真正的类别:在主实现文件(在.m文件中)内声明并在主实现文件中实现的方法的附加声明。这用于为您的类定义其他私有接口。
在代码中,似乎它是一个类别@interface
,除了括号是空的,省略了类别名称。此外,它是一个奇怪的类别,因为它没有匹配的@implementation
。
这对你有用吗?
您可以在标题中将该属性定义为(retain, readonly)
,然后在类扩展中将其重新定义为(retain)
。 @synthesize
现在将创建getter和setter访问器。
让我们来看看方法3的一个例子。
#import <Foundation.h>
@interface MyClass : NSObject
{
id _myValue;
}
@property (retain, readonly) id myValue;
@end
//
#import "MyClass.h"
@interface MyClass ()
@property (retain) id myValue;
@end
@implementation MyClass
@synthesize myValue = _myValue;
@end
现在该属性实际上包含一个setter的事实是你的实现细节,同时你没有编写自己的setter。如果您自己编写它可能会稍微快一些,并且您不必注意retain
/ release
调用和赋值操作的顺序。
答案 1 :(得分:0)
我最终通过覆盖数据对象上的setValue:forUndefinedKey:方法得到了一个解决方法。如果键名是outCome,只需返回而不调用super。