Search code examples
iosnsmutablearraykey-value-codinguncaught-exception

NSMutableArray key value coding error


Looking for help diagnosing the following error:

* Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFBoolean 0x39d40da8> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key Cricket.'

Here's the code:

NSMutableArray *soundNames = [[NSMutableArray alloc] initWithObjects:@"Random", @"Cricket", @"Mosquito", @"Fly", @"Owl", @"Scratching", @"Whistle", nil];

NSNumber *noObj = [NSNumber numberWithBool:NO];
NSMutableArray *soundValues = [[NSMutableArray alloc] initWithObjects:noObj, noObj, noObj, noObj, noObj, noObj, noObj, nil];

NSMutableDictionary *soundDict = [[NSMutableDictionary alloc]initWithObjectsAndKeys:soundNames, @"Sound Names", soundValues, @"Sound Values", nil]];

- (void)setSoundDictValue:(BOOL)value forKey:(NSString *)key
{
    [[soundDict objectForKey:@"Sound Values"] setValue:[NSNumber numberWithBool:value] forKey:key];
    …
}

Thanks Tony.


Solution

  • You are building the dictionary incorrectly. Why not just do:

    NSMutableDictionary *soundDict = [@{
        @"Random" : @NO,
        @"Cricket" : @NO,
        @"Mosquito" : @NO,
        @"Fly" : @NO,
        @"Owl" : @NO,
        @"Scratching" : @NO,
        @"Whistle" : @NO
    } mutableCopy];
    

    Then your setSoundDictValue:forKey: method becomes:

    - (void)setSoundDictValue:(BOOL)value forKey:(NSString *)key {
        sound[key] = @(value);
    }
    

    The problem with your code is easier to see if you split it up:

    - (void)setSoundDictValue:(BOOL)value forKey:(NSString *)key {
        NSArray *sounds = [soundDict objectForKey:@"Sound Values"];
        [sounds setValue:[NSNumber numberWithBool:value] forKey:key];
    }
    

    As you can see, you try to call setValue:forKey: on an NSArray.