Re: copy & isEqual nightmares
Re: copy & isEqual nightmares
- Subject: Re: copy & isEqual nightmares
- From: Uli Kusterer <email@hidden>
- Date: Tue, 14 Feb 2012 14:30:27 +0100
On 13.02.2012, at 18:29, Quincey Morris wrote:
> 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.
No. Keep in mind, this restriction is with regard to NSDictionary. NSDictionary probably uses the hash as the key under which it will store its contents in a tree structure of sorts. If you change an object's hash, the tree would be invalid, and would need to be re-built. However, this applies only to the *keys* of an NSDictionary. The values do not decide the order of the objects in a dictionary, so as long as you only modify the values, you're safe.
That's the reason why NSDictionary copies its keys. If you give it an NSMutableString as the key and then change it, the dictionary would go invalid. By copying the key, it gets turned into an immutable NSString and can't be changed by anyone.
The aforementioned restriction is only an issue for a class like a (fictional) NSSortedArray, which would sort its contents by their values, and if it used a tree or similar structure, that tree would become invalid when an object in it is modified in a way that changes its hash.
> 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.
Not at all. It simply restricts the "must not change" part above. It's a public method. Anyone can call -hash, and -isEqual: and the likes probably use it internally to shortcut their comparisons.
> 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.
Not at all. In fact, it is what NSMutableString does.
> 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]
Then the hashes wouldn't work for collection classes. The section you quoted says "If two objects are equal (as determined by the isEqual: method), they must have the same hash value." Also, -copyWithZone: is said to return "a new instance that’s a copy of the receiver." By all definitions of the word "copy" I've found, that means it's equivalent to the original. That should include the hash and -isEqual:.
I think your confusion comes from the issue that each object defines its own equality semantics. In simpler words, what properties make sense to compare and which don't. If an object has a cache of some sorts in some ivars, that obviously doesn't make much sense to compare. Also, for some objects, equality is an impossible thing to tell. E.g. how would you compare two NSNotificationCenters? Now given, most such objects wouldn't implement -copy, but I don't think I've ever seen an object where it made sense to both *not* have copies be equal and support the -copy method.
Cheers,
-- Uli Kusterer
"The Witnesses of TeachText are everywhere..."
_______________________________________________
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