Comment remplacez-vous correctement isEqual:
dans Objective-C? Le "catch" semble être que si deux objets sont égaux (comme déterminé par la isEqual:
méthode), ils doivent avoir la même valeur de hachage.
La section Introspection du Cocoa Fundamentals Guide contient un exemple sur la façon de remplacer isEqual:
, copié comme suit, pour une classe nommée 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;
}
Il vérifie l'égalité du pointeur, puis l'égalité des classes, et compare enfin les objets à l'aide isEqualToWidget:
, qui vérifie uniquement les propriétés name
et data
. Ce que l'exemple ne montre pas , c'est comment passer outre hash
.
Supposons qu'il existe d'autres propriétés qui n'affectent pas l'égalité, par exemple age
. Ne doit pas la hash
méthode est surchargée de sorte que seule name
et data
affecte le hachage? Et si oui, comment feriez-vous cela? Ajoutez simplement les hachages de name
et data
? Par exemple:
- (NSUInteger)hash {
NSUInteger hash = 0;
hash += [[self name] hash];
hash += [[self data] hash];
return hash;
}
Est-ce suffisant? Existe-t-il une meilleure technique? Et si vous avez des primitives, comme int
? Les convertir NSNumber
pour obtenir leur hachage? Ou des structures comme NSRect
?
( Brain fart : A l'origine écrit "bitwise OR" avec |=
. Signifie ajouter.)
if (![other isKindOfClass:[self class]])
- Cela signifie techniquement que l'égalité ne sera pas commutative. C'est-à-dire A = B ne signifie pas B = A (par exemple si l'un est une sous-classe de l'autre)