overriden isEqual method not getting called every time during comparisons

ios, objective-c

Solution

Please read the discussion about `isEqual:` in the NSObject Protocol in the Reference Library.

You'll find that for objects which are inside a collection (such as an NSArray), `hash` might be used to determine whether two objects are actually the same. If two pointers are actually pointing to the same object, there is no need to check for equality - hence `isEqual:` never gets called.

The solution as suggested by the reference library is to implement `hash` in your subclass as well.

Problem

I have a class called ``` Contact; ``` In `Contact` I have `(simple version to test, no hash yet)` ``` - (BOOL)isEqual:(id)other { if (other == self) return YES; if (!other || ![other isKindOfClass:[self class]]) return NO; return NO; } ``` I do: ``` NSMutableArray *arr = [[NSMutableArray alloc] init]; Contact *contact = [Contact new]; [arr addObject:contact] // I expect my isEqual to be called here but it does not get called [arr containsObject:contact] // this evaluates to true somehow!!! ``` However if I add a another object to type `NSString`, then it gets called for comparing String object but not for the contact object. Which means ``` [arr addObject:@""] // so now arr has two elements // here I expect two calls to isEqual but only one gets there // when comparing string object against Contact [arr containsObject:contact] ``` Why is `isEqual` not getting called in cases I mentioned above??

Original source