NSMenuItem与BOOL的值绑定

时间:2010-02-11 05:59:33

标签: objective-c cocoa cocoa-bindings appkit

我遇到了一些绑定NSMenuItem绑定到BOOL的“值”的问题。

我将问题简化为:

1)菜单项必须调用改变BOOL值的action方法,否则它不起作用(即如果NSButton调用一个改变BOOL值的方法,那么菜单项不会更新)

2)即使action方法使BOOL保持不变(即enabled = YES),菜单项的“值”仍会交替显示。

有什么想法吗?我很困惑!

以下是代码:

MenuBindings_AppDelegate.h

#import <Cocoa/Cocoa.h>

@interface Menu_BindingsAppDelegate : NSObject <NSApplicationDelegate> 
{   
   BOOL foo;
}

- (IBAction)toggle:(id)sender;
- (IBAction)makeYes:(id)sender;

@property BOOL foo;

@end

Menu_BindingsAppDelegate.m

@implementation Menu_BindingsAppDelegate

@synthesize foo;

- (IBAction)toggle:(id)sender
{
   [self setFoo:!foo];
}

- (IBAction)makeYes:(id)sender
{   
   [self setFoo:YES];
}

@end

在我的笔尖中,我有一个连接到-makeYes:action的按钮和一个连接到-toggle:action的菜单项。菜单项的“值”绑定绑定到app delegate的“foo”属性。

感谢。

1 个答案:

答案 0 :(得分:2)

Cocoa Bindings使用 Key-Value Observing (KVO)来获取模型对象更改的通知。为了让观察者(包括使用绑定的任何视图)注意到模型中的更改(您的BOOL值),您必须使用 Key-Value Coding 兼容的访问者更新模型方法。如果您只是直接设置ivar的值,则不会发送任何KVO通知。

您可以自己实现KVC访问器,也可以声明属性并在实现中使用@synthesize关键字让编译器为您创建兼容的访问器。

这是您实现KVC兼容访问器的方法:

//YourModel.h
@interface YourModel : NSObject
{
    BOOL enabled;
}
- (BOOL)enabled;
- (void)setEnabled:(BOOL)flag;
@end

//YourModel.m
@implementation YourModel
- (BOOL)enabled
{
    return enabled;
}
- (void)setEnabled:(BOOL)flag
{
    enabled = flag;
}
@end

这就是你使用Objective-C 2.0属性语法做同样的事情:

//YourModel.h
@interface YourModel : NSObject
{
    BOOL enabled;
}
@property BOOL enabled;
@end

//YourModel.m
@implementation YourModel
@synthesize enabled;
@end

然后您可以致电[yourModel setEnabled:YES],任何已注册的KVO观察员(包括您的菜单装订)都会收到通知。

或者,您可以致电yourModel.enabled = YES,如果可以的话,将使用正确的KVC访问者。

我上传了一个sample project来演示它是如何完成的。