Reputation: 148
I know that I can override hash and isEqual
to check 2 instances equality. Xcode has the default snippet and doucument https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/ObjectComparison.html as following
- (BOOL)isEqual:(id)other
{
if (other == self) {
return YES;
} else if (![super isEqual:other]) { //WHAT is this line mean ?
return NO;
} else {
return <#comparison expression#>;
}
}
- (NSUInteger)hash
{
return <#hash expression#>;
}
Okay,
other == self
check two objects' pointers.
if ![super isEqual:other]
, what is this line means ? If super object is not equal other, return NO ? Then it will always return NO
, the step 3 will not be executed.
Am I wrong ?
Thanks.
Upvotes: 2
Views: 477
Reputation: 1224
There is a slightly different between Hash and isEqual in Objective-C.
First of all, NSObject
checks equality with another object with the method isEqual:
and basically, two objects may be equal to another, if they share a common set of observable properties.
Hashing in object comparison is an extra step in determining collection membership, which will faster your operation.
This will explain a little bit about hash and isEqual
I hope this would be helpful. For reference, you can visit this link http://nshipster.com/equality/
Upvotes: 0
Reputation: 6336
It's a typical implementation in a class-hierarchy, that is, if your class derives from a super class that has its own meaningful isEqual:
implementation. In that case it is wise to let the super class test the equality of the common properties. If the common part is not equal, then there is no chance that the derived objects are equal.
It is not needed if you derive directly from NSObject
.
Actually, you'll need an extra step as well:
- (BOOL)isEqual:(id)other
{
if (other == self) {
return YES;
} else if (![super isEqual:other]) {
return NO;
} else if (![other isKindOfClass:[MyClass class]]) {
return NO; // comparing incompatible objects
} else {
MyClass *myOther = (MyClass *) other;
return <#compare between self and myOther#>;
}
}
Upvotes: 4
Reputation: 130102
Let's look at one example of class inheritance:
@interface A : NSObject
@property (nonatomic, assign, readwrite) NSInteger fieldA;
@end
@interface B : A
@property (nonatomic, assign, readwrite) NSInteger fieldB;
@end
Now, if you want to implement equality on A
, then you want to base it on the equality of fieldA
:
// A equality
- (BOOL)isEqual:(id)other {
...
return [self fieldA] == [other fieldA];
}
When you are implementing equality on B
, you need two conditions - first you have to make sure that fieldA
is equal and then you have to make sure that fieldB
is equal.
// B equality
- (BOOL)isEqual:(id)other {
...
return [super isEqual:other] && [self fieldB] == [other fieldB];
}
That's exactly what the [super isEqual:other]
is doing - it checks the equality requirement of the superclass, that is fieldA
.
To be honest, this isEqual:
template is not very good. It is missing one of the most important things and that is the class equality check:
if (![other isMemberOfClass:[self class]]) {
return NO;
}
You don't need this check only when you never mix instances of different classes. However, when you start putting instances of A
and B
into the same array/dictionary etc. you will have crashes when trying to compare instances of A
with instances of B
.
Upvotes: 0