Re: copy & isEqual nightmares
Re: copy & isEqual nightmares
- Subject: Re: copy & isEqual nightmares
- From: Quincey Morris <email@hidden>
- Date: Sun, 12 Feb 2012 17:10:23 -0800
On Feb 12, 2012, at 16:25 , James Maxwell wrote:
> I have an object with isEqual set up to help me limit the number of "unique" objects I can put in a Dictionary. Basically, the object has a few properties which account for "equality", and some properties that don't matter. For example, propA and propB are used in isEqual, but propC isn't. The point is that I can create a set with objects where only propA and propB are different, and propC just is irrelevant. Maybe that seems weird, but it's what I need.
Nope, that's not at all weird.
> But what I don't get is how hash plays into all this. I've always read that I have to override hash when I override isEqual, but I don't exactly understand what that means or does. What I've done is to make a hash that is equal when two objects have the same values for propA and propB (ignoring propC). That's how I interpreted the few threads I've read about overriding hash…
Here's the rule:
If 'isEqual' returns YES for two objects, those objects must have the same hash.
That's what you just said, but it's more useful to think of it the other way round:
If two objects have different hashes, 'isEqual' must return NO.
In other words, comparing the hashes is a fast way to limiting the cases where a more expensive 'isEqual' check is actually necessary.
That's a useful performance optimization, since 'isEqual' could be very expensive in some classes, but not the real reason why there are hashes. Instead, hashes are used to make storage of object pointers in sets and dictionaries more efficient. (Those collections' storage is implemented with a combination of random and sequential accesses. Hashes are used to limit the amount of sequential accessing needed to find a particular pointer, but it only works well if the hashes of the objects you create are reasonably randomly distributed.)
> But what I need to do in my code, right now, is to copy an object, then alter some properties of the copy, but not the original -- a typical reason for wanting a copy. But I'm seeing that the copy has the same hash and appears to be the same object, since changing properties of the copy changes the original. So does the system see the matching hashes as identical objects, not just the collection classes?
Nope.
> Do I have to manually implement some sort of deepCopy method?
Nope.
> Or, can I just change hash, so that the copy is a different instance, without losing the functionality I need for collections?
It sounds like you haven't implemented the NSCopying protocol properly. If your object is mutable, you should always make a new object, so if you're seeing the same object, you've left out a step.
If the object is immutable (like a NSString or NSNumber, say), then the copy can be implemented as just another (strong) reference to the original, since the properties can't be changed.
(Note that you can create object copies without following the NSCopying protocol. A copied object is just an object that has properties that make the copy 'isEqual' to the original. You can do this in an ad-hoc way, but conforming to NSCopying seems like good form, generally.)
_______________________________________________
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