Fast enumeration of a dictionary iterates over keys not objects: documentation.
Use enumerateKeysAndObjectsUsingBlock:
instead. It is probably just as fast - see discussion here.
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.
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]);
}