Tutorial :iPhone/Objective-C array enumeration crashes



Question:

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?


Solution:1

edit Louis pointed out in one of the comments that -[NSDictionary valueForKey:] will forward on to objectForKey: unless the key begins with @. Source However, I'd still change it to use objectForKey: just for semantic clarity.

Use objectForKey: instead of valueForKey:. They have very different semantics and implementations. valueForKey:@"headerTitle" will look for an NSDictionary method called headerTitle and return the result of that method (or if it doesn't exist, will likely crash), whereas objectForKey: actually goes and looks stuff up in the dictionary's hash table structure to find the object you're looking for.


Solution:2

-[NSDictionary valueForKey:@"Foo"] actually calls -[NSDictionary objectForKey:@"Foo"] for you.

So either will work for NSDictionaries.

As for the crashes, when you run this in the debugger are you not seeing a stack trace? poiCategories is an allocated/inited NSMutableArray?


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »