forum

Home / DeveloperSection / Forums / Best practices for overriding isEqual and hash

Best practices for overriding isEqual and hash

Anonymous User 2005 15-Sep-2015

How to properly override isEqual: in Objective-C? The "catch" seems to be that if two objects are equal (as determined by the isEqual: method), they must have the same hash value.
The Introspection section of the Cocoa Fundamentals Guide does have an example on how to override isEqual:, copied as follows, for a class named ShowWidget:

- (BOOL)isEqual:(id)showOther {
    if (showOther == self)
        return YES;
    if (!showOther || ![showOther isKindOfClass:[self class]])
        return NO;
    return [self isEqualToWidget:showOther];
}
- (BOOL)isEqualToWidget:(ShowWidget *)showWidget {
    if (self == showWidget)
        return YES;
    if (![(id)[self name] isEqual:[showWidget name]])
        return NO;
    if (![[self data] isEqualToData:[showWidget data]])
        return NO;
    return YES;
}

It checks pointer equality, then class equality, and finally compares the objects using isEqualToWidget:, which only checks the name and data properties. What the example doesn't show is how to override hash.
Let's assume there are other properties that do not affect equality, say age. Shouldn't the hash method be overridden such that only name and data affect the hash? And if so, how would you do that? Just add the hashes of name and data? For example:

- (NSUInteger)myHash {
    NSUInteger myHash = 0;
    myHash += [[self name] myHash];
    myHash += [[self data] myHash];
    return myHash;
}

Is that sufficient? Is there a better technique? What if you have primitives, like int? Convert them to NSNumber to get their hash? Or structs like NSRect?


Updated on 16-Sep-2015
I am a content writter !

Can you answer this question?


Answer

1 Answers

Liked By