【问题标题】:Read from NSDictionary to NSMutableArray Crash when there's only one element当只有一个元素时,从 NSDictionary 读取到 NSMutableArray 崩溃
【发布时间】:2011-08-12 16:08:17
【问题描述】:

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

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];

如果我有零个或两个或更多&lt;area&gt;,这工作正常,但如果我只有一个,它会崩溃,就像我上面显示的那样。

这里有一些我认为可能有用的信息,

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 检查一个对象是否是一个类型,有没有办法让它告诉我它是什么类型的对象?

【问题讨论】:

  • 您能否提供您在哪里以及如何填充 myDict 字典的代码?

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


【解决方案1】:

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

【讨论】:

  • 谢谢!我在中午解决了这个问题,但没有机会更新。当有多个时它变成 NSDictionary 数组,而当只有一个时它变成 NSDictionary。我使用isKindOfClass 来确定和分配。
【解决方案2】:

尝试将您的调用拆分为不同的行,以查看错误发生的位置。

而不是这个:

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];

【讨论】:

  • 由于[areas objectForKey:@"area"] 不是NSDictionary,我删除了第4 行并将第5 行更改为myArray = [[[NSMutableArray alloc] initWithArray[areas objectForKey:@"area"]] autorelease];,这就是它崩溃的地方。所以现在我必须弄清楚什么时候只有一个元素,当我做[areas objectForKey:@"area"]时,我会得到什么样的对象,以便我可以相应地初始化我的数组。
  • 我认为它崩溃了,因为 area 是一个数组,而您试图在其上调用 [areas objectForKey:@"area"],这是一个 NSDictionary 方法。
【解决方案3】:

实际上我有点惊讶它适用于 2 个或更多 &lt;area&gt; 节点。当您有多个区域时,您的代码不会将所有单独的&lt;area&gt; 节点放在一个数组中吗?因此,当您尝试调用[areas objectForKey:@"area"] 时,它应该会崩溃,因为区域是NSArray,而不是NSDictionary。它是一个字典是没有意义的,因为它不能有重复的键。因此,如果是,那么它会覆盖存储在area 键中的值(如果有多个)。

我怀疑您的代码在某处被颠倒了 - 如果有 2 个或更多节点(导致某些覆盖),它将把 &lt;area&gt; 节点放入字典中,如果只有 1 个节点(导致调用 NSArray 不存在的方法而崩溃),但它应该做相反的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-19
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    相关资源
    最近更新 更多