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

发布于 2024-11-29 02:12:40 字数 2715 浏览 0 评论 0原文

我有一个 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];

如果我有零个或两个或更多,这工作正常,但如果我只有一,就像我展示的那样 多于。

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

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

I have a NSDictionary that I get data from a xml file.

The xml file looks like this:

<?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>

I read this xml into a NSDictionary, say myDict, then I want to store it in a NSMutableArray, say myArray, I use:

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

This works fine if I have zero, or two or more <area>, but it crash if I have only one, just like what I showed above.

Here are some information that I think might be helpful,

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'

Part of the call stack:

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

EDIT:

I think I might just have a clue what's going on, so I add a if-else statement like that:

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

When there's only one element, it gives me "no array", but I'm still using initWithArray to crate my NSMutableArray.

So I can check if a object is or isn't a type using isKindOfClass, is there a way for it to just tell me what kind of object it is?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

倾城花音 2024-12-06 02:12:40

您没有说明如何将 XML 转换为字典,但从 XML 的结构和错误来看, area 似乎是一个字典,而不是一个数组,因此您可以不要将其用作 initWithArray: 的参数。据推测,当有许多 area 元素时,从 XML 到对象的映射会将其转换为字典数组,但当只有一个元素时则不会。

You don't say how you've translated the XML to a dictionary, but both from the structure of your XML and from the error, area appears to be an dictionary, not an array, so you can't use it as the argument to initWithArray:. Presumably your mapping from XML to objects is turning it into an array of dictionaries when there are many area elements but not when there's only one.

北渚 2024-12-06 02:12:40

尝试将呼叫分成不同的线路,以查看错误发生的位置。

而不是这个:

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

Try breaking up your calls into different lines to see where the error is happening.

Instead of this:

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

Try this:

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];
梦中的蝴蝶 2024-12-06 02:12:40

实际上,我有点惊讶它适用于 2 个或更多

节点。当您有多个区域时,您的代码是否会将所有单独的

节点放入一个数组中?因此,当您尝试调用 [areas objectForKey:@"area"] 时,它应该会崩溃,因为 Areas 是一个 NSArray,而不是 NSDictionary。它是一本字典是没有意义的,因为它不能有重复的键。因此,如果是,那么它会覆盖存储在 area 键中的值(如果有多个)。

我怀疑你的代码在某个地方被颠倒了 - 如果有 2 个或更多(导致一些覆盖),它将

节点放入字典中,如果有,则将它们放入数组中只有 1 (导致调用 NSArray 不支持的方法时崩溃),但它应该做相反的事情。

I'm actually a little surprised that it works for 2 or more <area> nodes. When you have more than one area, wouldn't your code put all the individual <area> nodes in an array? So when you try to call [areas objectForKey:@"area"] it should crash because areas is an NSArray, not an NSDictionary. It wouldn't make sense that it is a dictionary because it can't have duplicate keys. So if it is, then it is overwriting the value stored in the area key if there is more than one.

I have a suspicion that your code is reversed somewhere - it is putting the <area> nodes in a dictionary if there is 2 or more (causing some overwriting) and putting them in an array if there is only 1 (causing the crash for calling a method that NSArray doesn't hvave), but it is supposed to do the opposite.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文