Comment contourner correctement isEqual:
en Objective-C ? Le "piège" semble être que si deux objets sont égaux (comme déterminé par la fonction isEqual:
), ils doivent avoir la même valeur de hachage.
El Introspection de la section Guide des fondamentaux de Cocoa a 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é des pointeurs, puis l'égalité des classes, et enfin compare les objets à l'aide de la fonction isEqualToWidget:
qui ne vérifie que le name
y data
propriétés. Ce que l'exemple n'a pas montre comment passer outre hash
.
Supposons qu'il existe d'autres propriétés qui n'affectent pas l'égalité, par exemple age
. Ne devrait-on pas hash
de telle sorte que seule la méthode name
y data
affectent le hachage ? Et si oui, comment le feriez-vous ? Il suffit d'ajouter les hachages de name
y 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 en NSNumber
pour obtenir leur hachage ? Ou des structures comme NSRect
?
( Perturbation cérébrale : A l'origine, j'ai écrit "bitwise OR" les deux ensemble avec |=
. Je voulais ajouter.)
2 votes
if (![other isKindOfClass:[self class]])
- Cela signifie techniquement que l'égalité ne sera pas commutative. C'est-à-dire que A = B ne signifie pas B = A (par exemple, si l'un est une sous-classe de l'autre).0 votes
Le lien vers la documentation est mort, maintenant archivé sur Introspection