Re: copy & isEqual nightmares
Re: copy & isEqual nightmares
- Subject: Re: copy & isEqual nightmares
- From: James Montgomerie <email@hidden>
- Date: Tue, 14 Feb 2012 12:32:14 +0000
On 13 Feb 2012, at 17:29, Quincey Morris wrote:
> 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.
I don't think this is as concrete as you are analysing it to be.
Take a mutable string as the canonical example - obviously its hash should change when its contents changes (and it should no longer be isEqual: with a copy of its older self). It's up to the user of the string to ensure that they don't mutate it while it's being used in a collection (i.e. as a key) to ensure predictable program behaviour.
Jamie.
_______________________________________________
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