views:

58

answers:

2

So I have an NSDictionary that contains several objects with properties (key:values), but the issue is that I need them in a specific order.

Stored as an NSArray is a list of objects that I would like to use as keys for the NSDictionary.

I can output the NSArray and NSDictionary to the Console, however when I to access each of the values keyed to "filename" with:

for(NSUInteger i=0; i<[images count]; i++)
NSLog(@"%@", [[dictionary objectForKey:[images objectAtIndex:i]] objectForKey:@"filename"]);

I get all nulls.

Anyone have any idea? I'm assuming it's because my [images objectAtIndex:i] returns something other than a string, however I've tried slappin in a (NSString *) and I still get nulls.

Any help would be greatly appreciated!

A: 

If the things in the dictionary aren't dictionaries, shouldn't that second objectForKey be valueForKey?

JWWalker
If they aren't dictionaries, then they would not respond to `objectForKey:`, so the code would stop in the first iteration with an exception; the questioner would not see a series of `nil`s.
Peter Hosey
A: 
NSLog(@"%@", [[dictionary objectForKey:[images objectAtIndex:i]] objectForKey:@"filename"]);

I get all nulls.

Getting the key from the array is working fine. Either dictionary does not have an object for the key you retrieved, or the dictionary you retrieved does not have an object for the key @"filename".

I'm assuming it's because my [images objectAtIndex:i] returns something other than a string, however I've tried slappin in a (NSString *) and I still get nulls.

First, NSStrings are not the only valid keys. Any copyable object is usable as a dictionary key.

More importantly, remember that you never work directly with object structures, but with pointers to objects. objectAtIndex: returns a pointer to an object; when you cast its return value, you're telling the compiler that objectAtIndex: will return a pointer to an NSString object. Casting a pointer does not change the pointer itself; it only tells the compiler what to expect at the other end of that pointer. If objectAtIndex: is returning pointers to, say, Foo objects, casting them to pointers to NSString objects will not make them point to NSString objects; they will still point to Foo objects, so looking those objects up in a dictionary whose keys are strings will still fail.

The other thing to consider is: Why don't you know what is in this array? You created the array. You populated the array. Surely, then, you should know what's in it. objectAtIndex: does not return anything but (a pointer to) an object that is in the array.

If you think objectAtIndex: is returning objects that are not valid keys, then you should examine the array using either NSLog or the debugger. Check what the array contains and what those objects' classes are.

More probably, the array does contain objects that would be valid as keys, but are not keys in the dictionary, or it does contain objects that are keys in the dictionary, but the dictionaries that are the objects for those keys do not contain the @"filename" key. Examine both the array and the outer dictionary.

One other caveat, which may be what's tripping you up: If you're keeping mutable strings in the array, and those are the keys you initially inserted dictionaries into the outer dictionary under, and you mutate these strings, that makes them not match the keys in the outer dictionary. Remember that dictionaries copy their keys (this is why keys need to be copyable); you mutate the string you have in the array, but the dictionary made a copy previously, and that copy does not change. (Such is the point of making a copy: Whoever makes the copy—in this case, the dictionary—wants to keep the object as it is, without receiving any mutations that occur later on.)

So, if you want to revise any of the strings, you'll have to replace them in the array and store the outer dictionary's object for the old key under the new key. You'll also have to take steps to prevent duplicate keys; the dictionary only holds one object per key, while the array can contain the same object any number of times.

Peter Hosey
Wow, thanks man - while typing up the question I did kind of realize that I have a little bit more understanding to achieve regarding NSDictionaries.
Smokin Joe