NSDictionary没有响应objectForKey和valueForKey

时间:2012-01-12 14:42:29

标签: iphone objective-c ios dictionary nsdictionary

我有以下

// this code is inside cellForRowAtIndexPath for a TableViewController

id answer = [self.answers objectAtIndex:indexPath.row];
if ([answer respondsToSelector:@selector(objectForKey)]) {
    cell.textLabel.text = [answer valueForKey:@"answer_id"];
} else {
    // I'm ending up here, instead of the cell.textLabel being set
    [NSException raise:@"Answer is of invalid class" format:@"It should be able to respond to valueForKey, class: %@", [answer class]];
}

其中self.answers设置为

// the question that gets passed here is a parsed single object 
// from the `/questions` path
- (NSArray *)answersForQuestion:(NSDictionary *)question {
    NSString *contents = [self loadContentsForPath:[question valueForKey:@"question_answers_url"]];
valueForKey:@"question_answers_url"]];
    NSDictionary *data = [contents JSONValue];
    NSArray *answers = [data valueForKey:@"answers"];
    return answers;
}

- (NSString *)loadContentsForPath:(NSString *)path {
    NSString *wholeURL = [@"http://api.stackoverflow.com/1.1" stringByAppendingString:path];    
    return [NSString stringWithContentsOfURL:[NSURL URLWithString:wholeURL] encoding:NSUTF8StringEncoding error:nil];
}

我正在为加载问题做同样的事情,但这看起来很好 当我尝试[answers valueForKey:@"answer_id"]时,答案失败。

我认为这不是JSON解析器的问题,因为它适用于/questions数据。

当调试器停止异常并且我尝试右键单击时 - >在answers打印说明,我得到了

Printing description of answer:
<CFBasicHash 0x6ec1ec0 [0x1474b38]>{type = mutable dict, count = 13,
entries =>
    1 : <CFString 0x6ec57d0 [0x1474b38]>{contents = "down_vote_count"} = <CFNumber 0x6e1dc00 [0x1474b38]>{value = +0, type = kCFNumberSInt32Type}
    2 : <CFString 0x6ec4ee0 [0x1474b38]>{contents = "last_activity_date"} = <CFNumber 0x6ec5780 [0x1474b38]>{value = +1326379080, type = kCFNumberSInt64Type}
    3 : <CFString 0x6ec44b0 [0x1474b38]>{contents = "community_owned"} = <CFBoolean 0x1474f68 [0x1474b38]>{value = false}
...

对我而言似乎是一个常规哈希。我试过了objectForKeyvalueForKey这两个都没有用,即

exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0x6b2a330'

当我做的时候

cell.textLabel.text = [answer objectForKey:@"answer_id"];

3 个答案:

答案 0 :(得分:3)

实际上,堆栈溢出的api会发回一个数字。也就是说,为密钥answer_id存储的值是字典中的NSNumber,而不是NSString,您应该相应地对待它。

答案 1 :(得分:3)

:是方法名称的一部分,因此您需要执行以下操作:

if ([answer respondsToSelector:@selector(objectForKey:)]) {

然后使用objectForKey:,而不是valueForKey:。第一种是访问字典中的对象,后者是所谓的键值编码。所以它是:

id answer = [self.answers objectAtIndex:indexPath.row];
if ([answer respondsToSelector:@selector(objectForKey:)]) {
    cell.textLabel.text = [answer objectForKey:@"answer_id"];
} else {
    [NSException raise:@"Answer is of invalid class" format:@"It should be able to respond to objectForKey:, class: %@", [answer class]];
}

最后但并非最不重要的是,您从answer字典中获取的对象看起来像是NSNumber,而不是NSString。因此,您可能希望将文本设置更改为:

cell.textLabel.text = [[answer objectForKey:@"answer_id"] description];

答案 2 :(得分:0)

你可以使用: -

NSDictionary *answer = [self.answers objectAtIndex:indexPath.row];
if ([answer respondsToSelector:@selector(objectForKey)]) {
    cell.textLabel.text = [answer valueForKey:@"answer_id"];
} else {
    [NSException raise:@"Answer is of invalid class" format:@"It should be able to respond to valueForKey, class: %@", [answer class]];
}

 id answer = [self.answers objectAtIndex:indexPath.row];
if (answer isKindOfClass:[NSDictionary class])
{
  cell.textLabel.text = [answer valueForKey:@"answer_id"];
    } else {
        // I'm ending up here, instead of the cell.textLabel being set
        [NSException raise:@"Answer is of invalid class" format:@"It should be able to respond to valueForKey, class: %@", [answer class]];
    }