2012-04-18 16 views
13

¿Hay una manera de determinar si una clase es adecuado como una llave y funcionará como se espera, por ejemplo, quiero usar NSIndexPath como una clave en NSDictionary pero no sé por cierto, si dos instancias NSIndexPath diferentes con los mismos valores enteros siempre devolverán el mismo valor hash.clave Adecuado para NSDictionary

Respuesta

9

documento IsEqual de NSObject de Apple dice:

Si dos objetos son iguales, deben tener el mismo valor hash. Este último punto es particularmente importante si define isEqual: en una subclase y tiene la intención de poner instancias de esa subclase en una colección. Asegúrese de también define hash en su subclase.

Mira el siguiente código:

NSIndexPath *indexPath1 = [NSIndexPath indexPathForRow:0 inSection:0]; 

NSIndexPath *indexPath2 = [NSIndexPath indexPathForRow:0 inSection:0]; 

NSObject *obj1 = [[NSObject alloc] init]; 
NSObject *obj2 = [[NSObject alloc] init]; 

NSLog(@"NSIndexPath isEqual's Result: %d", [indexPath1 isEqual:indexPath2]); 
NSLog(@"NSObject isEqual's Result: %d", [obj1 isEqual:obj2]); 

salida Resultado:

Resultado de NSIndexPath IsEqual: 1

Resultado de

NSObject IsEqual: 0

La aplicación o f NSObject IsEqual es que Comare la dirección de dos objetos, e implementación de hash es la dirección de ese objeto de devolución.

NSIndexPath se hereda de NSObject, según resultado de salida NSIndexPath IsEqual, aplicación IsEqual de NSIndexPath debe reemplazar el método IsEqual de superclase, y NSIndexPath también reemplazar el método de hash de la superclase.

En la deserción;, NSIndexPath también cumplen con el protocolo NSCopying.

Así NSIndexPath se puede utilizar como clave de la clase NSDictionary.

+1

Por lo tanto, debe probar si la implementación de NSObjects de isEqual: y hash se anulan y asumirán siempre, lo cual no es irrazonable. Podría plantear un error en contra de Apple, ya que creo que si una clase anula es Equal: y el hash debe documentarse. –

+0

¡Estoy de acuerdo contigo! El documento de Apple no es lo suficientemente claro en el método isEqual: y hash. – xzgyb

+1

@NathanDay: Creo que deberías plantear un error si hay una clase para la cual tendría algún sentido el anular esos métodos, pero no es así. – Chuck

4

cómo un objeto se comporta como una tecla depende de cómo se implementa IsEqual :. Esto determinará si dos teclas colisionan.

Por ejemplo, las rutas de índice son iguales - y por lo tanto chocarán - cuando los caminos tienen el mismo conjunto de índices. De modo que el diccionario verá dos objetos distintos que describen la misma ruta como la misma clave ... probablemente cómo le gustaría que fuera.

+1

Mi entendimiento es el valor de hash de también es importante, supongo que es una buena suposición de que NSIndexPaths implementan IsEqual: y el hash de una manera que se comportará como se espera.¿Pero es eso todo lo que hay, solo una buena suposición? Estaba buscando un protocolo o documentación que dijera que los métodos isEqual: y hash se anulan en lugar de depender de la implementación de NSObjects. –

+0

Un objeto es igual si su valor hash es el mismo que el valor hash del otro, por lo general. Esto también hace que el hash sea muy importante. Para una clave DEBE tener una clase que produzca confiablemente el mismo valor hash para el mismo valor del objeto, y un valor hash distinto para cada valor que el objeto podría ser. Entonces, una manera fácil de comparar los dos valores sería ver si sus valores hash coinciden :). – borrrden

+1

De acuerdo con la documentación de Apple para NSDictionary, los objetos clave también deben cumplir con el protocolo NSCopying, que NSIndexPath sí lo hace. – bneely

2

Hay tres requisitos para llaves NSDictionary:

  1. compatibilidad con el protocolo del NSCopying
  2. método -hash razonable
  3. IsEqual

NSIndexPath debe estar bien.

+0

Pero, cómo sabes, imagino que NSIndexPath debería estar bien, pero no lo sé con certeza. De hecho, solo sé que NSString está bien porque se usa con tanta frecuencia. NSNumber, NSDate, NSURL I ASSUME están bien, NSValue No lo sé, quizás esto es un error en la documentación. –

+0

Bueno, solo hay una forma segura de averiguarlo: ¡pruébalo! :-) Si mira NSIndexPath.h, verá que obedece el protocolo NSCopying. También puede ver que tiene una variable de instancia "_hash". Y sabemos que admite isEqual, por lo que puedo decir, debería funcionar bien. Este es un buen lugar para usar una prueba unitaria. Y, sí, la documentación debería ser mejor. – EricS

Cuestiones relacionadas