从 NSDictionary 读取到 NSMutableArray 当只有一个元素时崩溃
我有一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您没有说明如何将 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 toinitWithArray:
. Presumably your mapping from XML to objects is turning it into an array of dictionaries when there are manyarea
elements but not when there's only one.尝试将呼叫分成不同的线路,以查看错误发生的位置。
而不是这个:
试试这个:
Try breaking up your calls into different lines to see where the error is happening.
Instead of this:
Try this:
实际上,我有点惊讶它适用于 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 anNSArray
, not anNSDictionary
. 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 thearea
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 thatNSArray
doesn't hvave), but it is supposed to do the opposite.