In my interface I have an NSTextField who’s value is bound to an NSArrayController's selection.selectedType.title. All of the NSArrayController's objects are custom objects each with two methods:
- (MYType *)selectedType;
- (void)setSelectedType: (MYType *)type;
The don’t have an iVar selectedType. However, they do have an iVar holding all MYType objects. The code boils down to this:
- (MYType *)selectedType
{
if (someIndex == 0)
return [types objectAtIndex: 0];
else
return [self typeWithIndex: someIndex];
}
- (void)setSelectedType: (MYType *)type
{
someIndex = [type index];
}
MYType objects got a NSString *title iVar with a corresponding @property and synthesize.
Whenever I call setSelectedType:, the changes are immediately visible in the NSTextField and everything seems to work but I get a log message saying:
Cannot remove an observer NSArrayController 0x141160 for the key
path “selectedType.title” from MYType 0x1a4830, most
likely because the value for the key “selectedType” has
changed without an appropriate KVO notification being sent. Check the
KVO-compliance of the MYType class.
I tried encapsulating the setSelectedType: method with willChangeValueForKey: and didChangeValueForKey: and then I still got a log message but a different one:
Cannot remove an observer NSKeyValueObservance 0x1c7570 for the key
path “title” from MYType 0x1a4be0 because it is not registered as an
observer.
First, use accessors. Don’t access your ivars directly. You’re bypassing the KVO for
someIndexbecause you modify the ivar directly. Don’t touch ivars directly unless you have to.You also need to let KVO know that
selectedTypedepends onsomeIndex(and/orsomeStuff; it’s not clear from your distilled code).This tells the KVO system that whenever
someIndexchanges, it causes an implicit change inselectedType. See Registering Dependent Keys.