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 nameet 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 hashméthode est surchargée de sorte que seule nameet dataaffecte le hachage? Et si oui, comment feriez-vous cela? Ajoutez simplement les hachages de nameet 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 NSNumberpour 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)