当只有一个元素时,从NSDictionary读取到NSMutableArray崩溃

时间:2011-08-12 16:08:18

标签: objective-c ios cocoa-touch nsarray nsdictionary

我有一个NSDictionary,我从xml文件中获取数据。

xml文件如下所示:

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<root>
<customer>
    <areas>
        <area>
            <company>ABC</company>
            <state>OO</state>
            <area_name>Somename</area_name>
            <count>123</count>
            <total_custs>123123</total_custs>
        </area>
       <area>
            <company>BCD</company>
            <state>EE</state>
            <area_name>Somename2</area_name>
            <count>1233</count>
            <total_custs>11233</total_custs>
        </area>
    </areas>
</customer>
</root>

我将此xml读入NSDictionary,说myDict,然后我想将其存储在NSMutableArray中,比如myArray,我使用:

myArray = [[NSMutableArray alloc] initWithArray:[[[[myDict objectForKey:@"root"] objectForKey:@""customer"] objectForKey:@"areas"] objectForKey:@"area"]] autorelease];

如果我有零,或两个或更多 <area>,这样可以正常工作,但如果我只有一个就会崩溃,就像我上面所示的那样。

以下是我认为可能有用的一些信息,

2011-08-12 09:04:40.343 TEST[28595:ef03] -[__NSCFDictionary getObjects:range:]: unrecognized selector sent to instance 0x588af50
2011-08-12 09:04:40.345 TEST[28595:ef03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary getObjects:range:]: unrecognized selector sent to instance 0x588af50'

调用堆栈的一部分:

0   CoreFoundation                      0x011fc5a9 __exceptionPreprocess + 185
1   libobjc.A.dylib                     0x01350313 objc_exception_throw + 44
2   CoreFoundation                      0x011fe0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3   CoreFoundation                      0x0116d966 ___forwarding___ + 966
4   CoreFoundation                      0x0116d522 _CF_forwarding_prep_0 + 50
5   CoreFoundation                      0x011f7fc5 -[NSArray initWithArray:range:copyItems:] + 245
6   CoreFoundation                      0x0115fdc0 -[NSArray initWithArray:] + 96

编辑:

我想我可能只是知道发生了什么,所以我添加了一个if-else语句:

if ([[[[[myDict objectForKey:@"root"] objectForKey:@""customer"] objectForKey:@"areas"] objectForKey:@"area"] isKindOfClass:[NSArray class]]) {
    ALog(@"is array!");
}
else
{
    ALog(@"not array!");
}

当只有一个元素时,它给了我“没有数组”,但我仍然使用initWithArray来创建我的NSMutableArray。

所以我可以使用isKindOfClass检查一个对象是否是一个类型,有没有办法告诉我它是什么类型的对象?

3 个答案:

答案 0 :(得分:1)

你没有说你是如何将XML翻译成字典的,但是从XML的结构和错误中,area似乎都是字典,而不是数组,所以你可以不要将它用作initWithArray:的参数。据推测,当存在许多area元素时,从XML到对象的映射会将其转换为字典数组,而不是只存在一个时。

答案 1 :(得分:0)

尝试将您的通话分成不同的行,以查看错误发生的位置。

而不是:

myArray = [[NSMutableArray alloc] initWithArray:[[[[myDict objectForKey:@"root"] objectForKey:@""customer"] objectForKey:@"areas"] objectForKey:@"area"]] autorelease];

试试这个:

NSDictionary *root = [mydict objectForKey:@"root"];
NSDictionary *customer = [root objectForKey:@"customer"];
NSDictionary *areas = [customer objectForKey:@"areas"];
NSDictionary *area = [areas objectForKey:@"area"];
myArray = [[[NSMutableArray alloc] initWithArray: area] autorelease];

答案 2 :(得分:0)

我真的有点惊讶它适用于2个或更多<area>个节点。当您有多个区域时,您的代码不会将所有单个<area>节点放在一个数组中吗?因此,当您尝试拨打[areas objectForKey:@"area"]时,它会崩溃,因为区域是NSArray,而不是NSDictionary。它是字典是没有意义的,因为它不能有重复的键。因此,如果是,则覆盖存储在area密钥中的值(如果有多个)。

我怀疑你的代码在某处被反转 - 如果有2个或更多(导致一些覆盖),它会将<area>个节点放在字典中,如果只有1个则将它们放在一个数组中(导致崩溃调用NSArray没有hvave的方法,但它应该做相反的事情。