cocoansdictionaryfast-enumeration

Fast enumeration with NSDictionary holding NSDictionary objects


I have an NSDictionary with four objects. Each object is an NSDictionary containing thousands of objects. I have verified through logging of the description of the top level dictionary that it contains what it is supposed to. However, when I run the code below, to enumerate the objects in that top level dictionary, the debugger is showing an error, indicating that the returned object is a sting rather than a dictionary.

Here is the code:

for(id synsetsForPos in dictionaryOfSynsetDictionaries) {
    NSLog(@"synsetsForPos is class of %@ with description %@", [synsetsForPos class], [synsetsForPos description]);

(I originally typed synsetsForPos as NSDictionary, but the results described here are the same.)

In the debugger, I halt at the log statement to get this in the console:

(lldb) po [synsetsForPos class]
(id) $2 = 0x016e2c8c __NSCFConstantString
(lldb) po [[dictionaryOfSynsetDictionaries objectForKey:@"n"] class]
(id) $3 = 0x016d3e0c __NSCFDictionary
(lldb) po [[dictionaryOfSynsetDictionaries objectForKey:@"r"] class]
(id) $6 = 0x016d3e0c __NSCFDictionary
(lldb) po [[dictionaryOfSynsetDictionaries objectForKey:@"v"] class]
(id) $7 = 0x016d3e0c __NSCFDictionary
(lldb) po [[dictionaryOfSynsetDictionaries objectForKey:@"a"] class]
(id) $8 = 0x016d3e0c __NSCFDictionary
(lldb) po [dictionaryOfSynsetDictionaries allKeys]
(id) $10 = 0x653662a0 <__NSArrayI 0x653662a0>(
r,
n,
v,
a
)

Then, letting the log statement execute, I get this:

2012-11-24 22:32:41.069         [6037:fb03] synsetsForPos is class of __NSCFConstantString with description r
(lldb) 

followed by this error message:

2012-11-24 22:41:21.287         [6037:fb03] -[__NSCFConstantString countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0x1faf8

I don't understand what's going on here, why this is not being treated as a dictionary in the fast enumeration code.


Solution

  • Fast enumeration of a dictionary iterates over keys not objects: documentation.

    Use enumerateKeysAndObjectsUsingBlock: instead. It is probably just as fast - see discussion here.