This is a bit complex.
I’ve created an array (NSArray) called pointsOfInterest.
The elements of this array are NSDictionary objects. Each dictionary has two keys, “headerTitle” and “rowObjects.” The value for “headerTitle” is a simple NSString; the object for “rowObjects” is another NSArray of objects; each of these is a custom class.
See the code below.
for (NSDictionary *dict in pointsOfInterest) {
NSArray *keys = [dict allKeys];
for (NSString *key in keys) {
//NSLog(@"Key %@",key);
}
NSString *category = [dict valueForKey:@"headerTitle"];
[poiCategories addObject:category];
}
So, I’m enumerating through the array, getting individual dictionary objects into dict. I then run through all of its keys – if I uncommented the NSLog line, it would display something like this:
2010-08-06 14:00:17.236 TourGuide[4479:207] Key headerTitle
2010-08-06 14:00:17.237 TourGuide[4479:207] Key rowObjects
2010-08-06 14:00:17.238 TourGuide[4479:207] Key headerTitle
2010-08-06 14:00:17.239 TourGuide[4479:207] Key rowObjects
It then constructs a new, flat array, containing the values from all of the “headerTitle” keys.
First, I’m well aware that I should be able to do this:
poiCategories = [[pointsOfInterest valueForKey:@"headerTitle"] retain]
And get the values for the various “headerTitle” keys. Doing that, however, crashes the app. What’s weird, is that the above for construct works fine… IF I leave in the internal for loop. If I remove that for loop, and its useless NSLog, leaving just this:
for (NSDictionary *dict in pointsOfInterest) {
NSString *category = [dict valueForKey:@"headerTitle"];
[poiCategories addObject:category];
}
Then it crashes. It does not grace me with any kind of trappable error that I can find.
Any reason anyone can think of?
edit Louis pointed out in one of the comments that
-[NSDictionary valueForKey:]will forward on toobjectForKey:unless the key begins with@. Source However, I’d still change it to useobjectForKey:just for semantic clarity.Use
objectForKey:instead ofvalueForKey:. They have very different semantics and implementations.valueForKey:@"headerTitle"will look for anNSDictionarymethod calledheaderTitleand return the result of that method (or if it doesn’t exist, will likely crash), whereasobjectForKey:actually goes and looks stuff up in the dictionary’s hash table structure to find the object you’re looking for.