在用相同类型的另一个实例替换目标对象的实例后,如何保持 Cocoa 绑定正常工作?

发布于 2024-08-05 04:25:52 字数 1231 浏览 1 评论 0原文

我希望能够使用绑定来使我的 GUI 与动态加载的对象保持同步,但是一旦我用另一个相同类型的对象替换有问题的对象,绑定就会中断并且 GUI 会停止更新。这里有一些代码可以帮助您理解我的意思:

在我的界面中,我有一个实例变量来保存有问题的对象:

@interface AppDelegate : NSObject {
    CustomObject *anObject; // This object has a "NSString *textValue" property
}

然后在我的实现中,我实例化该对象:

- (id) init {
    self = [super init];
    if (self != nil) {
        anObject = [[CustomObject alloc] init];
    }
    return self;
}

在 Interface Builder 中,我将文本字段的“值”绑定到“anObject.textValue”。

当我调用此方法时:

[anObject setValue:@"Changed anObject.textValue!" forKey:@"textValue"];

然后文本字段会更新以反映新值。

但我想要做的是显示在应用程序其他地方完成一些工作后给出的对象的值。所以我所做的是:

- (void)setCustomObject:(CustomObject *)newObject {
    anObject = newObject;
}

现在这个操作的结果似乎打破了从 GUI 到 CustomObject 实例 (anObject) 的绑定,考虑到绑定对象已被另一个实例替换,这似乎是合乎逻辑的。

我想知道的是,是否有一种方法可以使动态创建的 CustomObject 实例保持绑定功能,而不必通过 bind:toObject:forKeyPath:options: 或类似方法以编程方式重新绑定每个控件这将需要(据我所知)使用 IBOutlet 来获取控件,然后能够将它们绑定到我的新对象中的值(在我看来,这将使绑定在我的情况下毫无用处)。这是唯一的解决方案还是有更好、更干净的方法来处理这个问题?

我已经阅读了developper.apple.com 和其他地方有关绑定的大量文档,但我没有找到任何似乎谈论此特殊情况的内容。

预先感谢您的宝贵时间!

I would like to be able to use bindings to keep my GUI synchronized to a dynamically loaded object, but as soon as I replace the object in question with another one of the same type the bindings break and the GUI stops updating. Here's some code to help you understand what I mean:

In my interface I have an instance variable to hold the object in question:

@interface AppDelegate : NSObject {
    CustomObject *anObject; // This object has a "NSString *textValue" property
}

Then in my implementation I instantiate the object:

- (id) init {
    self = [super init];
    if (self != nil) {
        anObject = [[CustomObject alloc] init];
    }
    return self;
}

In Interface Builder I have the "value" of a text field bound to "anObject.textValue".

When I call this method:

[anObject setValue:@"Changed anObject.textValue!" forKey:@"textValue"];

then the text field updates to reflect the new value.

But what I want to do is display the values from an object which is given after doing some work elsewhere in the application. So what I did was this:

- (void)setCustomObject:(CustomObject *)newObject {
    anObject = newObject;
}

Now the result of this operation seems to break the bindings from the GUI to the CustomObject instance (anObject) which seems logical considering the bound object has been replaced by another instance.

What I want to know is if there is a way to keep the bindings functional with the dynamically created instance of CustomObject without having to re-bind every control programmatically through bind:toObject:forKeyPath:options: or similar which would require (to my knowledge) the use of IBOutlets to get a hold of the controls to then be able to bind them to the values in my new object (IMO this would make the bindings kind of useless in my situation). Is this the only solution or is there a better, cleaner way to deal with this?

I have read a good bunch of documents on developper.apple.com and elsewhere regarding bindings but I did not find anything which seems to talk about this particular case.

Thanks in advance for your time!

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

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

发布评论

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

评论(2

谈下烟灰 2024-08-12 04:25:52

具体来说,我认为问题在于您的 setter 方法被称为 -setCustomObject: 而不是 -setAnObject:。如果你做了这样的更改,我认为 KVO 将被调用,并且你绑定的文本字段将被更新。

Abizern 关于它泄漏的注释(如果您不使用 GC)仍然适用。你的设置器应该看起来像:

- (void)setAnObject:(CustomObject *)newObject {
    if (anObject != newObject) {
        [anObject release];
        anObject = [newObject retain];
    }
}

To be specific, I think the problem was that your setter method was called -setCustomObject: instead of -setAnObject:. If you made just that change I think that KVO would be invoked, and your bound textfields would be updated.

Abizern's note about it leaking (if you're not using GC) still applies though. Your setter should instead look something like:

- (void)setAnObject:(CustomObject *)newObject {
    if (anObject != newObject) {
        [anObject release];
        anObject = [newObject retain];
    }
}
芯好空 2024-08-12 04:25:52

查看有关 键值观察的这些文档. 这应该向您展示如何以符合 KVO 的方式更改属性。

或者,将 anObject 设置为属性:

@interface AppDelegate : NSObject {
    CustomObject *anObject; // This object has a "NSString *textValue" property
}
@property (retain) CustomObject *anObject;
...
@end

@interface AppDelegate
@synthesize anObject;

...
@end

然后在更改 anObject 实例时,使用属性语法。

self.anObject = newObject;

这将为你处理 KVO 的事情。

笔记:
除非你有 GC 打开你的 setCustomObject: 方法泄漏。

Have a look at these docs on Key Value observing. This should show you how to change properties in a KVO compliant way.

Alternatively, set up anObject as a property:

@interface AppDelegate : NSObject {
    CustomObject *anObject; // This object has a "NSString *textValue" property
}
@property (retain) CustomObject *anObject;
...
@end

@interface AppDelegate
@synthesize anObject;

...
@end

Then when changing the anObject instance, use property syntax.

self.anObject = newObject;

This will take care of the KVO stuff for you.

note:
Unless you have GC turned on your setCustomObject: method leaks.

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