NSDictionary for循环异常

时间:2011-08-22 09:46:08

标签: iphone objective-c cocoa nsdictionary

我使用这部分代码的方法:

NSDictionary *tmpDict = [self getJsonDictionary];

NSInteger tmpID;

for (NSDictionary *d in tmpDict) {
    tmpID = [[d objectForKey:@"id"] integerValue];
}

tmpDict是一个大小可变的NSDictionary。如果tmpDict包含至少2个对象(2个NSDictionary),它运行良好,但如果它只包含1个对象(1个NSDictionary)则抛出此异常:

 -[NSCFString objectForKey:]: unrecognized selector sent to instance 0x4e866d0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString objectForKey:]: unrecognized selector sent to instance 0x4e866d0'

为什么这样?如果tmpDict只有一个对象,如何修复?

可能for (NSDictionary *d in tmpDict)是问题,当tmpDict有一个对象dNSCFString时,为什么会这样?

- 更新

问题是当tmpDict有1个项目(一个NSDictionary)时for (NSDictionary *d in tmpDict)获取字典中的每个键/值项,这就是异常的原因。否则如果tmpDict有2个以上的项目是NSDictionary的NSDictionary,它运行良好。我需要一种方法来使用for循环来解决这个问题。想法?

- 更新2 *

实际上这段代码有效,但它是多余的:

if ([tmpObject isKindOfClass:[NSDictionary class]]) {
    tmpID = [[tmpObject objectForKey:@"id"] integerValue];
    tmpProp2 = [tmpObject objectForKey:@"prop2"];
    tmpProp3 = [tmpObject objectForKey:@"prop3"];
    tmpProp4 = [tmpObject objectForKey:@"prop4"];
} else if ([tmpObject isKindOfClass:[NSArray class]]) {
    for (NSDictionary *d in tmpObject) {
        tmpID = [[d objectForKey:@"id"] integerValue];
        tmpProp2 = [d objectForKey:@"prop2"];
        tmpProp3 = [d objectForKey:@"prop3"];
        tmpProp4 = [d objectForKey:@"prop4"];
    }
}

需要改进。

2 个答案:

答案 0 :(得分:3)

我很惊讶它实际上是有效的。对于词典,快速枚举枚举。这就是为什么它告诉你-objectForKey:已被发送到NSCFString,因为来自JSON的字典的键总是一个字符串。

你应该这样做:

for (id d in [tmpDict objectEnumerator])
{
    // Objects in a JSON dictionary aren't necessarily dictionaries
    if([d isKindOfClass:[NSDictionary class]])
    {
         tmpID = [[d objectForKey:@"id"] integerValue];
    }
}

它可能与两个词典一起使用的一个可能原因是顶级项目实际上是数组而不是字典。如果你有:

[ { "id" : 1 }, { "id" : 2 } ]

您的JSON解析器将为您提供NSArray,而不是NSDictionary,即使您认为您的顶级项目是字典,也可以使用您的代码进行解析。

编辑:看过您的更新后,我确信这就是正在发生的事情。如果您有一个对象,那么您的JSON字符串看起来像:

{ "id" : 1, "prop2" : "value1", "prop3" : "value1", "prop4" : "value1" }

如果你有两个对象,它可能看起来像:

[
        { "id" : 1, "prop2" : "value1", "prop3" : "value1", "prop4" : "value1" },
        { "id" : 2, "prop2" : "value1", "prop3" : "value1", "prop4" : "value1" }
]

注意方括号,表示JSON数组。

答案 1 :(得分:2)

发生错误是因为你的tmpDict变量中有一个NSString类型的对象,所以你可以使用它。

 for (id *d in tmpDict)
{
    if([d isKindOfClass:[NSDictionary class]])
        tmpID = [[d objectForKey:@"id"] integerValue];
    else
        tmpID = [(NSString *)d intValue];
}

而不是

for (NSDictionary *d in tmpDict) {
    tmpID = [[d objectForKey:@"id"] integerValue];
}