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

发布于 2024-08-20 05:15:41 字数 495 浏览 3 评论 0原文

有谁知道如何防止 Cocoa 绑定将值设置回绑定属性,但仍然触发默认操作选择器?

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

...

@property(readonly) NSString* outCome;

-(void)otherMethodsAffectOutCome;

...

我将 NSTextField 与结果属性绑定在一起,并在默认操作处理程序中调用 -otherMethodAffectOutCome,我希望 will/didChangeValueForKey 能够触发 outCome 属性的观察者并返回 NSTextField。

但它不起作用, NSTextField 会崩溃,因为它尝试通过 setOutCome 方法设置更改后的文本...我想我需要 NSTextField 观察属性值更改,但不要尝试在文本更改时设置值,应该如何我这样做?

谢谢! -乔尼

Does anyone know how to prevent Cocoa binding to set values back to the bound property but still fires the default action selector?

I am trying to bind a NSTextField to a readonly NSString property on my data object.
My data Object is like

...

@property(readonly) NSString* outCome;

-(void)otherMethodsAffectOutCome;

...

I bound the NSTextField with the outcome property and in default action handler I called -otherMethodAffectOutCome, and I hope will/didChangeValueForKey to fire outCome property's observer and back the NSTextField.

But it doesn't work, NSTextField will crash because it tries to set changed text back via setOutCome method... I think I need NSTextField watch the property value changes, but don't try to set values back on text change, How should I do that?

Thanks!
-Jonny

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心如狂蝶 2024-08-27 05:15:41

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

  1. 只需将属性更改为不为只读即可。由于它是 Objective-C 对象,因此应该对其进行retained。

  2. 如果您需要将属性以readonly形式公开给外界,您可以仅在实现中手动定义setOutCome:;对于外界来说,该属性似乎是只读的,除非某个聪明人直接调用 -setOutCome:。 Cocoa Bindings 技术本身就是其中之一。

    这是一个坏主意,除非您非常了解 retain setter 应该如何工作并且您对此非常小心。另外,您还必须将该属性转换为nonatomic——这是 iOS 上的建议设置,但不是 OS X 上的设置。

  3. 最后,这是这三个解决方案中的最佳解决方案< /strong>,方法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 调用和赋值的顺序运营。

Since you have your own model object already, there are two options better than overriding -setValue:forUndefinedKey:.

  1. Simply change the property not to be readonly. Since it's an Objective-C object, it should be retained.

  2. If you need to have the property exposed as readonly to outside world, you can either manually define setOutCome: solely in the implementation; to the outside world it'll seem like the property is read-only, unless some wisehead comes along and directly calls -setOutCome:. One such wisehead is Cocoa Bindings technology itself.

    This is a bad idea unless you know very well how a retain setter should work and if you're very careful about it. Also, you'll have to turn the property into nonatomic -- the suggested setting on iOS, but not on OS X.

  3. Finally, here is the best solution of these three, a variant of method 2. Aside from "categories", classes can also have "extensions". Simply explained, you should think of these as not-really-categories: additional declarations of methods declared inside your main implementation file (inside the .m file) and implemented inside your main implementation file. This is used to define additional private interface for your class.

    In code, it seems as if it's a category @interface, except parentheses are empty, omitting the category name. Also, it's a weird category in that it doesn't have a matching @implementation.

    How is this useful for you?

    You can define the property in your header as (retain, readonly), but then redefine it as (retain) in the class extension. @synthesize will now create both getter and setter accessors.

So let's take a look at an example of method 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

Now the fact that the property actually contains a setter is your implementation detail, while at the same time you didn't write your own setter. It's possibly slightly faster that it'd be if you wrote it yourself, and you didn't have to be careful about the order of retain/release calls and of the assignment operations.

相对绾红妆 2024-08-27 05:15:41

我最终通过重写数据对象上的 setValue:forUndefinedKey: 方法想出了一个解决方法。如果键名为outCome,则直接返回,无需调用super。

I came up with a workaround finally by overriding the setValue:forUndefinedKey: method on my data object. if the key name is outCome, just return without calling super.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文