Re: NSDictionary key types
Re: NSDictionary key types
- Subject: Re: NSDictionary key types
- From: Jon Sigman <email@hidden>
- Date: Fri, 7 Jan 2011 10:36:17 -0800 (PST)
The underlying issue I was having was how to know when different objects used as
keys might be reasonably expected to match, especially if they weren't generated
the same way (as with [NSNumber stringValue] and [NSString ...]).
I guess the long answer is "its complicated", and the short answer is "just use
NSStrings".
Thanks to all, I think I'm getting the hang of it.
________________________________
Kirk Kerekes wrote:
If you are insufficiently confused, I thought I would add some additional
confusion.
1. Don't worry overmuch about hash values. Particularly, never succumb to the
temptation to store them persistently.
The -hash algorithm for a particular class may vary with OS version. It
certainly has before.
It certainly varies from class to class.
2. Do not expect items like NSString and NSNumber to return the same hash values
for humanly-similar entities like [NSNumber numberWithNSInteger: 12345] and
[NSString stringWithString: @"12345"].
3. Do not expect collection hashes to take into account the entire contents of
the collection. -isEqual does, however.
4. It is entirely feasible to use a non-string object as a dictionary key, so
long as it obeys the general requirements for dictionary keys. You can use a
NSNumber as a dictionary key, a NSDate as a dictionary key, a NSDictionary as a
dictionary key, any immutable object that implements -hash and -copy, pretty
much. Including your own.
A problem with using collections as dictionary keys is that even though the
collection may be immutable, there is no guarantee that the objects in the
collection are.
5. Good practice would be to try to stick to using NSStrings as dictionary keys.
This moves further towards compliance with property lists, and it is very nice
to be able to read/write an arbitrary dictionary as a property list. Also makes
debugging easier.
6. That dictionary keys are immutable leads to some nice efficiencies -- if you
define a key as a NSString literal:
#define MYKEY @"My Key";
(or)
NSString * myKey = @"My Key";
-- then every time you use MYKEY or myKey in a dictionary (or anywhere), the
dictionary key will be that specific global instance of that NSString -- a
singleton. You can create 1000 NSDictionaries containing a key "My Key", but
there will be only exactly one in-memory instance of that key. This means that
-isEqual on that key will always short-circuit to an address comparison, which
is about as efficient as you can get.
Speed and space optimization at a single stroke. Immutability is a lovely
attribute.
Of course, once you start saving and reloading NSDictionaries, you likely start
losing this niftyness, unless Apple has implemented undocumented optimizations
like coalescing new instances of NSStrings into a global string cache. They
might have done that, Apple likes that sort of thing, and it wouldn't be hard to
implement. It would be even more compelling on iOS, where storage, RAM and
computing power are comparatively scarce.
_______________________________________________
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