开发者

Read from NSDictionary to NSMutableArray Crash when there's only one element

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"] obj开发者_运维百科ectForKey:@""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?


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.


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜