Re: copy & isEqual nightmares
Re: copy & isEqual nightmares
- Subject: Re: copy & isEqual nightmares
- From: Quincey Morris <email@hidden>
- Date: Mon, 13 Feb 2012 09:29:17 -0800
On Feb 13, 2012, at 01:14 , Uli Kusterer wrote:
> The hash should be calculated from your object's values. If your object's ivars (those that are relevant to the hash) can be changed after creation, you must always recalculate your hash whenever one of them is modified (or mark it as invalid, and lazily recalculate it whenever someone next asks for the hash). If it really is the same object, you goofed and are somehow not copying your object. In that case changing the hash will not do much good, as you'll change the hash for both places that reference this single object. If you have two, the moment you change a value in it, the hash should change as well. If they have identical values, they should have identical hashes.
I'm not sure I absolutely understand what you said, but it doesn't sound right.
It's a mistake to calculate the hash from *mutable* object state, including ivars that "can be changed after creation". The NSObject protocol documentation on 'hash' is worth recalling:
> hash
> Returns an integer that can be used as a table address in a hash table structure. (required)
>
> - (NSUInteger)hash
> Return Value
> An integer that can be used as a table address in a hash table structure.
>
> Discussion
> If two objects are equal (as determined by the isEqual: method), they must have the same hash value. This last point is particularly important if you define hash in a subclass and intend to put instances of that subclass into a collection.
>
> If a mutable object is added to a collection that uses hash values to determine the object’s position in the collection, the value returned by the hash method of the object must not change while the object is in the collection. Therefore, either the hash method must not rely on any of the object’s internal state information or you must make sure the object’s internal state information does not change while the object is in the collection. Thus, for example, a mutable dictionary can be put in a hash table but you must not change it while it is in there. (Note that it can be difficult to know whether or not a given object is in a collection.)
There are 3 points to take away, beyond the basic requirements:
1. "the value returned by the hash method of the object must not change…". It sounded like you were contradicting this, above.
2. "… while the object is in the collection". This seems to promise that the only parts of the Cocoa frameworks that actually make use of the hash are the collection classes.
3. The hash is primarily intended to support hash table storage mechanisms. Any performance benefits in other contexts are secondary (and, given #2, aren't even necessarily valid if the object isn't in a collection).
Now, although #2 gives you permission to violate #1 while the object is *not* in a collection, its sounds like a terrible idea to do so.
Also, if the "they" in your last sentence refers to an object and its copy, then Ken already pointed out earlier in this thread that there's no requirement that:
[object isEqual: [object copy]]
although that would typically be expected. So, there's also no requirement that:
[object hash] == [[object copy] hash]
_______________________________________________
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