Question

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.

Was it helpful?

Solution

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

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

OTHER TIPS

In fast enumeration of dictionaries in Objective-C are returned values of keys. In your example, your for-loop is the same as for(NSString *synsetsForPos in [dictionaryOfSynsetDictionaries keys]).

What you need to add is get value for a particular key and work with it:

NSDictionary *value = [dictionaryOfSynsetDictionaries valueForKey:synsetsForPos];

The question is old but for future travelers another simple solution is to just specify the dictionary values in the for clause:

for(NSDictionary *synsetsForPos in [dictionaryOfSynsetDictionaries allValues]) {
    NSLog(@"synsetsForPos is class of %@ with description %@", [synsetsForPos class], [synsetsForPos description]);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top