Привязка значения NSMenuItem с помощью BOOL - PullRequest
3 голосов
/ 11 февраля 2010

У меня возникли некоторые проблемы, связанные с привязкой «значения» NSMenuItem к BOOL.

Я упростил задачу до этого:

1) Пункт меню должен вызвать метод действия, который изменяет значение BOOL, в противном случае он не работает (т. Е. Если NSButton вызывает метод, который изменяет значение BOOL, тогда меню элемент не обновится)

2) Даже если метод действия делает 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: и пункт меню, связанный с действием -toggle:. Привязка «value» пункта меню привязана к атрибуту «foo» делегата приложения.

Спасибо.

1 Ответ

2 голосов
/ 11 февраля 2010

Привязки какао используют Наблюдение значения ключа (KVO) для получения уведомления об изменениях в объектах модели. Чтобы изменения в модели (ваше значение BOOL) были замечены наблюдателями, включая любые виды, использующие привязки, вы должны обновить модель, используя Кодирование значения ключа - совместимые методы доступа. Если вы просто установите значение 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], и любые зарегистрированные наблюдатели КВО (включая привязку вашего меню) будут проинформированы об изменении.

Кроме того, вы можете позвонить yourModel.enabled = YES, который будет использовать надлежащие средства доступа KVC, если они доступны.

Я загрузил пример проекта , чтобы продемонстрировать, как это делается.

...