如何将可编辑的TextField绑定到只读属性

时间:2010-02-05 12:29:00

标签: cocoa-bindings

有没有人知道如何阻止Cocoa绑定将值设置回绑定属性但仍会触发默认操作选择器?

我正在尝试将NSTextField绑定到我的数据对象上的只读NSString属性。 我的数据对象就像

...

@property(readonly)NSString * outCome;

- (无效)otherMethodsAffectOutCome;

...

我将NSTextField绑定到results属性,并在默认操作处理程序中调用-otherMethodAffectOutCome,我希望/ didChangeValueForKey可以触发outCome属性的观察者并返回NSTextField。

但它不起作用,NSTextField会崩溃,因为它试图通过setOutCome方法设置更改后的文本...我想我需要NSTextField监视属性值更改,但不要尝试在文本更改时设置值,我该怎么做?

谢谢! -Jonny

2 个答案:

答案 0 :(得分:1)

由于您已拥有自己的模型对象,因此有两个选项比覆盖-setValue:forUndefinedKey:更好。

  1. 只需将属性更改为readonly即可。由于它是Objective-C对象,因此应该retain编辑。

  2. 如果您需要将该属性公开为readonly外部世界,您可以仅在实施中手动定义setOutCome:;对于外面的世界来说,看起来这个属性是只读的,除非有一些智者出现并直接调用-setOutCome:。其中一个明智之处是Cocoa Bindings技术本身。

    这是一个坏主意,除非你非常了解retain setter应该如何工作以及你是否非常小心。此外,您必须将该属性转换为nonatomic - iOS上的建议设置,但不能转换为OS X.

  3. 最后,这里是这三个的最佳解决方案,方法2的变体。除了“类别”,类也可以有“扩展”。简单地解释一下,您应该将这些视为非真正的类别:在主实现文件(在.m文件中)内声明并在主实现文件中实现的方法的附加声明。这用于为您的类定义其他私有接口。

    在代码中,似乎它是一个类别@interface,除了括号是空的,省略了类别名称。此外,它是一个奇怪的类别,因为它没有匹配的@implementation

    这对你有用吗?

    您可以在标题中将该属性定义为(retain, readonly),然后在类扩展中将其重新定义为(retain)@synthesize现在将创建getter和setter访问器。

  4. 让我们来看看方法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。