Re: The joys of people using valueForKey to get objects out of a dictionary.
Re: The joys of people using valueForKey to get objects out of a dictionary.
- Subject: Re: The joys of people using valueForKey to get objects out of a dictionary.
- From: Alex Zavatone <email@hidden>
- Date: Tue, 10 Nov 2015 13:52:45 -0500
- X_v_e_cd: 89b0c2fb84bf6eaa9cf41f2540646145
- X_v_r_cd: ed09c38783cc68d33bea780748a73237
On Nov 10, 2015, at 12:35 PM, Greg Weston wrote:
>
>
>> It's been about 4 or 5 years since I made this mistake but I've just seen a massive swath of code where every access of a dictionary object is using valueForKey instead of objectForKey.
>>
>> I've got a few examples of why this is a "really bad idea"™, ....
>
> I would like to see these examples, because I can't think of any reason why it should be a bad idea. Per the documentation, it's a wrapper around objectForKey: with one special case.
I'm looking at a large chunk of code that uses all dictionary object access using valueForKey. All of it is wrapped within @try/@catch blocks, implying that the original authors ran into lots of exceptions being raised and they didn't know why.
My main inclination for using objectForKey over valueForKey to access the object for a key within a dictionary is that objectForKey is actually a dictionary method while valueForKey is a method declared in the NSKeyValueCoding.h file.
I did find this example on SO yesterday, and this important issue with regards to missing keys.
http://stackoverflow.com/questions/1062183/difference-between-objectforkey-and-valueforkey
Here's a great reason to use objectForKey: wherever possible instead of valueForKey: - valueForKey: with an unknown key will throw NSUnknownKeyException saying "this class is not key value coding-compliant for the key ".
But according to Charles and Mike comment and my testing, it doesn't - in some cases.
Take this code on iOS 9:
NSDictionary *myStuff = [NSDictionary dictionaryWithObjectsAndKeys:@"a", @"A", nil];
po myStuff
{
A = a;
}
po [myStuff valueForKey:@"a"];
nil
// Just as Charles and Mike mentioned
po [myStuff objectForKey:@"a"];
nil
// Just as we expect
But if we remove the @ (obviously unintended), valueForKey causes an EXC_BAD_ACCES while objectForKey reports "error: string literal must be prefixed by '@'".
And David does state that whether an exception is thrown or not is implementation dependent.
From what Greg showed and in my testing, valueForKey will crater if you use an @ in your key name, something I haven't seen until I tested it.
If we're not using @ within our key names, I haven't seen much here that indicates why it's dangerous, nor why the code I'm looking at that uses valueForKey on dictionaries needs to be wrapped in @try/@catch statements.
For what we're doing on a daily basis, if we're not using @ within our keys, I still can't see anything concrete besides "objectForKey is an NSDictionary method" while "valueForKey is a KVO method".
Hmm.
Thanks to all for their input on this.
- Alex Zavatone
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden