Don't Understand KVC Error Using Array Operators

  • I can't understand why I'm getting an exception when I try to use the
    array operators.

    Here's what I'm trying to do.  One instance variable is a
    NSMutableArray named "contacts".  This array contains instances of
    objects that have a "call" property, which is an NSString.  I have
    another instance variable, also an NSString, named "exCall".  I want
    to find out whether any contact has a call property that equals exCall.

    (It's a ham radio logging program.  Yes, I know I'm a nerd, thanks.)

    The following method works:

    - (BOOL)callInLog
    {
        if (!contacts || ![contacts count] ||
            ![self exCall] || ![[self exCall] length])
            return NO;

        NSEnumerator *e = [[self contacts] objectEnumerator];
        QEContact *contact;
        while (nil != (contact = [e nextObject])) {
            if ([[contact call] isEqual:[self exCall]])
                return YES;
        } // while

        return NO;

    } // callsignInLog

    The following method throws an exception every time:

    - (BOOL)callInLog
    {
        if (!contacts || ![contacts count] ||
            ![self exCall] || ![[self exCall] length])
            return NO;

        return ([[self valueForKey:@"<contacts....>"]
                  containsObject:[self exCall]]);
    } // callsignInLog

    The message on the console is "Exception raised during posting of
    notification.  Ignored.  exception: '[<QELogModel 0x15c3a0>
    valueForUndefinedKey:]: this class is not key value coding-compliant
    for the key <contacts....>.'  invoked observer method:
    '*** -[NSTextField textDidEndEditing:]'  observer: 0x17a0a0
    notification name: 'NSTextDidEndEditingNotification'"

    Shouldn't the results of the two routines be identical?  If not, why
    not?

    (I'm running XCode v. 3.0 on a PPC machine that's running Leopard v.
    10.5.4.  The target SDK is Mac OS X 10.4 (Universal), with all that
    entails, such as no garbage collection or ObjC 2.0.)

    Thanks for any help,

    -Jon
  • On Jul 8, 2008, at 8:02 AM, Jon Gordon wrote:

    > I can't understand why I'm getting an exception when I try to use
    > the array operators.
    >
    > Here's what I'm trying to do.  One instance variable is a
    > NSMutableArray named "contacts".  This array contains instances of
    > objects that have a "call" property, which is an NSString.  I have
    > another instance variable, also an NSString, named "exCall".  I want
    > to find out whether any contact has a call property that equals
    > exCall.
    >
    > (It's a ham radio logging program.  Yes, I know I'm a nerd, thanks.)
    >
    > The following method works:
    >
    > - (BOOL)callInLog
    > {
    > if (!contacts || ![contacts count] ||
    > ![self exCall] || ![[self exCall] length])
    > return NO;
    >
    > NSEnumerator *e = [[self contacts] objectEnumerator];
    > QEContact *contact;
    > while (nil != (contact = [e nextObject])) {
    > if ([[contact call] isEqual:[self exCall]])
    > return YES;
    > } // while
    >
    > return NO;
    >
    > } // callsignInLog
    >
    >
    > The following method throws an exception every time:
    >
    > - (BOOL)callInLog
    > {
    > if (!contacts || ![contacts count] ||
    > ![self exCall] || ![[self exCall] length])
    > return NO;
    >
    > return ([[self valueForKey:@"<contacts....>"]
    > containsObject:[self exCall]]);
    > } // callsignInLog
    >
    >
    > The message on the console is "Exception raised during posting of
    > notification.  Ignored.  exception: '[<QELogModel 0x15c3a0>
    > valueForUndefinedKey:]: this class is not key value coding-compliant
    > for the key <contacts....>.'  invoked observer
    > method: '*** -[NSTextField textDidEndEditing:]'  observer: 0x17a0a0
    > notification name: 'NSTextDidEndEditingNotification'"

    valueForKey and valueForKeyPath are two different KVC accessors.
    You're using valueForKey and passing a dot-separated string. People
    usually use dot-separated strings as keypaths and pass them to
    valueForKeyPath.

    <more info than you really need to know to fix this>
    It's totally legal to pass dot-separated strings to value for key, but
    the NSObject built in logic won't be able to find a property or getter
    method with a sig like "<contacts....>". Mainly since
    that's not a valid obj-c ivar or method name.
    </more info than you really need to know to fix this>

    use valueForKeyPath instead of valueForKey.

    >
    >
    > Shouldn't the results of the two routines be identical?  If not, why
    > not?
    >
    > (I'm running XCode v. 3.0 on a PPC machine that's running Leopard v.
    > 10.5.4.  The target SDK is Mac OS X 10.4 (Universal), with all that
    > entails, such as no garbage collection or ObjC 2.0.)
    >
    > Thanks for any help,
    >
    > -Jon

    --------------------------
    RONZILLA
  • "D'oh!"
          -H. Simpson

    I made the change, and it works perfectly now.  Thanks very much!

    On Jul 8, 2008, at 11:44 AM, Ron Lue-Sang wrote:

    >
    > On Jul 8, 2008, at 8:02 AM, Jon Gordon wrote:
    >
    >> I can't understand why I'm getting an exception when I try to use
    >> the array operators.
    >>
    >> [SNIPPAGE]
    >
    > valueForKey and valueForKeyPath are two different KVC accessors.
    > You're using valueForKey and passing a dot-separated string. People
    > usually use dot-separated strings as keypaths and pass them to
    > valueForKeyPath.
    >
    > <more info than you really need to know to fix this>
    > It's totally legal to pass dot-separated strings to value for key,
    > but the NSObject built in logic won't be able to find a property or
    > getter method with a sig like "<contacts....>".
    > Mainly since that's not a valid obj-c ivar or method name.
    > </more info than you really need to know to fix this>
    >
    > use valueForKeyPath instead of valueForKey.