NSDictionary for loop exception
I've a method with this part of code:
NSDictionary *tmpDict = [self getJsonDictionary];
NSInteger tmpID;
for (NSDictionary *d in tmpDict) {
tmpID = [[d objectForKey:@"id"] integerValue];
}
tmpDict
is a NSDictionary with variable size. If tmpDict
contains at least 2 objects (2 NSDictionary) it works well but if it contains only 1 object (1 NSDictionary) throws this exception:
-[NSCFString objectForKey:]: unrecognized selector sent to instance 0x4e866d0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString objectForKey:]: unrecognized selector sent to instance 0x4e866d0'
Why this? And how to fix if tmpDict
has only 1 object?
Probably for (NSDictionary *d in tmpDict)
is 开发者_如何转开发the problem and when tmpDict
has 1 object d
is a NSCFString
, but why?
-- UPDATE
The problem is when tmpDict
has 1 item (one NSDictionary) the for (NSDictionary *d in tmpDict)
take every key/value item in the dictionary and this is the reason for exception. Otherwise if tmpDict
has 2+ items is a NSDictionary of NSDictionary and it works well. I need a way to fix this still using the for loop. Ideas?
-- UPDATE 2*
Actually this code works but it's redundant:
if ([tmpObject isKindOfClass:[NSDictionary class]]) {
tmpID = [[tmpObject objectForKey:@"id"] integerValue];
tmpProp2 = [tmpObject objectForKey:@"prop2"];
tmpProp3 = [tmpObject objectForKey:@"prop3"];
tmpProp4 = [tmpObject objectForKey:@"prop4"];
} else if ([tmpObject isKindOfClass:[NSArray class]]) {
for (NSDictionary *d in tmpObject) {
tmpID = [[d objectForKey:@"id"] integerValue];
tmpProp2 = [d objectForKey:@"prop2"];
tmpProp3 = [d objectForKey:@"prop3"];
tmpProp4 = [d objectForKey:@"prop4"];
}
}
It needs an improvement.
I'm surprised it works at all actually. For dictionaries, fast enumeration enumerates the keys. That's why it's telling you that -objectForKey:
has been sent to an NSCFString
because the key of a dictionary coming from JSON is always a string.
You should, perhaps, do this:
for (id d in [tmpDict objectEnumerator])
{
// Objects in a JSON dictionary aren't necessarily dictionaries
if([d isKindOfClass:[NSDictionary class]])
{
tmpID = [[d objectForKey:@"id"] integerValue];
}
}
One possible reason why it might work with two dictionaries is if the top level item is actually an array, not a dictionary. If you have:
[ { "id" : 1 }, { "id" : 2 } ]
your JSON parser will give you an NSArray
, not an NSDictionary
, which can be parsed with your code even though you assume your top level item is a dictionary.
Edit: Having seen your update, I'm sure this is what is happening. If you have one object, your JSON string is looking like:
{ "id" : 1, "prop2" : "value1", "prop3" : "value1", "prop4" : "value1" }
If you have two objects, it probably looks like:
[
{ "id" : 1, "prop2" : "value1", "prop3" : "value1", "prop4" : "value1" },
{ "id" : 2, "prop2" : "value1", "prop3" : "value1", "prop4" : "value1" }
]
Notice the square brackets, that means JSON array.
The error is occurring because there is an object of type NSString in your tmpDict variable, so you can use this.
for (id *d in tmpDict)
{
if([d isKindOfClass:[NSDictionary class]])
tmpID = [[d objectForKey:@"id"] integerValue];
else
tmpID = [(NSString *)d intValue];
}
instead of this
for (NSDictionary *d in tmpDict) {
tmpID = [[d objectForKey:@"id"] integerValue];
}
精彩评论