I have two UI components whose values are synchronized through user defaults. The first one is essentially an input field, the other a menu item. When the value of the input field changes, the key equivalent of the menu item changes through Cocoa bindings:
Input Field -> NSUserDefaultsController -> User Defaults
User Defaults -> NSUserDefaultsController -> Menu Item
This works perfectly for everything but a nil
value. For some reason I can’t store the actual nil
value in user defaults, I use an empty dictionary instead. On the other side that reads the value I have a transformer that “inflates” the empty dictionary into a nil
value.
Now, when I enter a non-nil value into the input field, it gets through to user defaults and is correctly propagated all the way to the menu item. When I enter an “empty” value, an empty dictionary is correctly stored in the user defaults, but the bound value of the menu item does not change.
What am I doing wrong?
What I did wrong was implementing the binding on the menu item as a hack. I introduced a keyCombo
property through a category:
@interface NSMenuItem (Combo)
@property(assign, nonatomic) MASShortcut *keyCombo;
@end
This is the property that gets bound to user defaults. Then, since I couldn’t easily add an instance variable in a category, I simply returned nil
in the getter:
@implementation NSMenuItem (Combo)
- (MASShortcut*) keyCombo
{
return nil;
}
/* setter omitted */
@end
This worked well until I wanted to set the property to nil
through bindings. Because the getter was always returning nil
, the Cocoa bindings machinery thought there was no need to update the property value, as it seemed to be nil
already.