我遇到了一些绑定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”属性。
感谢。
答案 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来演示它是如何完成的。