On Aug 20, 2009, at 20:51, Seth Willits wrote:

On Aug 20, 2009, at 2:31 PM, Alastair Houghton wrote:

The -hash method is important for objects that are used as keys in associative collections. So the worry about the hash value changing when an object's properties are altered is a bit of a red herring, because you *aren't supposed to change keys in associative collections*. If you do that in just about *any* implementation, ObjC or otherwise, you'll get undefined behaviour.

So, in practice, it's perfectly safe in 99.9% of cases to base your hash off your object's properties. In the specific case when you're mutating objects that are keys in associative collections (NSDictionary and NSSet being the primary examples, along with their CoreFoundation counterparts), if you change a property that affects *either* -isEqualTo: *or* -hash, you need to remove the object before mutating it and then add it back again afterwards.


The documentation, nor did many others' comments on this topic, make it clear that the mutability is only a problem for the *keys*. Others and the docs talk about (paraphrasing) "putting an object into a collection", not "using an object as a key in an associative collection."

Yes. I believe Alastair misspoke.

What he said is actually 99.9% true, but establishes a different point. The keys in a dictionary (or other keyed collection, like a map table) need to be immutable objects, but that's unrelated to the hash. Mutability in the keys would be bad, hash or no hash.

Separately, keyed collections use isEqual: on the keys to determine equality, so they need the isEqual:/hash to follow the rules. (Because the rules imply they can short-circuit some potentially expensive isEqual: invocations by trying fast hash comparison first. Whether they do that is an implementation detail we don't know.)

Separately, keyed collections may (and presumably do) use *key* hash values to distribute object values in memory. (Presumably, the key hashes may also be used to distribute key values in memory. That's an implementation detail we don't know.)

Separately, collections use isEqual: on the object values to determine equality, when they care. (I doubt that NSDictionary cares about object value equality, but NSSet certainly does, as does NSArray, when asked to compare objects.)

Separately, collections may (and presumably sometimes do) use *object* hash values to distribute objects in memory. (Obviously, NSSet does, and for all we know NSDictionary does too, to distribute object values that stored under the same key hash value -- though it would be an implementation detail.)

So object values must also follow the isEqual:/hash rules.

So AFAIK your reading of the documentation is absolutely correct. Object values cannot be mutated while in a collection, unless their hash value doesn't depend on the mutated properties. Key values cannot be mutated while used in a collection, period.

[Actually, for all I know, key values *can* be mutated while used in a collection, provided the hash value doesn't change, but even if it technically feasible it sounds so un-useful I'd argue it's better just to assert that it's not allowed.]

As far as the rest of this thread is concerned, I'd suggest we pay attention to what Clark Cox has said and ignore everything else. Of all our posts here today, he's the only one who's been *both* correct *and* brief simultaneously. :)


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to