Wie überschreiben Sie isEqual:
Objective-C richtig ? Der "Haken" scheint zu sein, dass zwei Objekte, wenn sie gleich sind (wie durch die isEqual:
Methode bestimmt), denselben Hashwert haben müssen.
Der Abschnitt Introspection des Cocoa Fundamentals Guide enthält ein Beispiel zum Überschreiben isEqual:
einer Klasse mit dem Namen MyWidget
:
- (BOOL)isEqual:(id)other {
if (other == self)
return YES;
if (!other || ![other isKindOfClass:[self class]])
return NO;
return [self isEqualToWidget:other];
}
- (BOOL)isEqualToWidget:(MyWidget *)aWidget {
if (self == aWidget)
return YES;
if (![(id)[self name] isEqual:[aWidget name]])
return NO;
if (![[self data] isEqualToData:[aWidget data]])
return NO;
return YES;
}
Es prüft die Zeigergleichheit, dann die Klassengleichheit und vergleicht schließlich die Objekte mit isEqualToWidget:
, wobei nur die Eigenschaften name
und überprüft data
werden. Was das Beispiel nicht zeigt, ist das Überschreiben hash
.
Nehmen wir an, es gibt andere Eigenschaften, die beispielsweise die Gleichheit nicht beeinflussen age
. Sollte nicht das hash
Verfahren, außer Kraft gesetzt wird , dass nur name
und data
den Hash beeinflussen? Und wenn ja, wie würden Sie das machen? Fügen Sie einfach die Hashes von name
und hinzu data
? Zum Beispiel:
- (NSUInteger)hash {
NSUInteger hash = 0;
hash += [[self name] hash];
hash += [[self data] hash];
return hash;
}
Ist das ausreichend Gibt es eine bessere Technik? Was ist, wenn Sie Primitive haben int
? Konvertieren Sie sie in NSNumber
, um ihren Hash zu bekommen? Oder Strukturen wie NSRect
?
( Brain Fart : Ursprünglich schrieb "bitwise OR" sie zusammen mit |=
. Gemeint hinzufügen.)
if (![other isKindOfClass:[self class]])
- Dies bedeutet technisch gesehen, dass Gleichheit nicht kommutativ ist. Dh A = B bedeutet nicht B = A (z. B. wenn eine eine Unterklasse der anderen ist)