2012-09-13 16 views
5

Supongo que tengo un objeto llamado Person que tiene la propiedad socialSecurityNumber, y esta clase anula el método isEqual: para devolver verdadero cuando las propiedades del número de la seguridad social son iguales. Y digo que he puesto un montón de instancias de Person en un NSDictionary.¿ObjectForKey de NSDictionary: se basa en la identidad o la igualdad?

Si ahora ejecutar un objeto newPerson, que pasa a tener el mismo número de la seguridad social como uno que ya están en el diccionario, y lo hago [myDictionary objectForKey:newPerson], tendrá que utilizar el isEqual: y volver SÍ, o va a comparar los punteros y volver NO?

sé que puedo escribir una simple prueba para averiguar, pero quiero entender cómo exactamente objectForKey: encuentra una coincidencia en un diccionario, y en general la consistencia de esto es a través del Cacao (es decir, hace NSArray 's indexofObject: funcionan de la misma?)

Respuesta

10

NSDictionary funciona como una tabla hash. Por lo tanto, usa -hash y -isEqual: para encontrar el objeto en el diccionario correspondiente a la clave especificada.

Para responder a su pregunta sobre NSDictionary, esta opción utiliza isEqual: y no compara el puntero. Pero también debe implementar hash además de isEqual: en su clase Person para que esto funcione.

Un par clave-valor dentro de un diccionario se llama una entrada. Cada entrada consta de un objeto que representa la clave y un segundo objeto que es el valor de esa clave. Dentro de un diccionario, las claves son únicas. Es decir, no hay dos claves en un solo diccionario iguales (según lo determinado por isEqual :).

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 definir también hash en su subclase.

Comenzando en el índice 0, cada elemento de la matriz se envía un IsEqual: mensaje hasta que se encuentra una coincidencia o se alcanza el final de la matriz. Este método pasa el parámetro anObject a cada mensaje isEqual :. Los objetos se consideran iguales si isEqual: (declarado en el protocolo NSObject) devuelve SÍ.


, siempre debe leer la documentación: como han señalado los extractos citados anteriormente, este tipo de detalles a menudo se explica en la "Discusión", o secciones de "consideración especial" de la documentación del método o en la sección "Descripción general" de la documentación de la clase en sí.

+0

¿Cómo implementar hash? –

+0

Como quiera, siempre que 2 objetos que sean iguales tengan el mismo hash, y que el hash no sea demasiado complejo para calcular. El algoritmo utilizado para eso depende de usted, pero dos objetos con diferentes valores hash siempre se considerarán diferentes, y dos objetos con el mismo valor hash se considerarán probablemente iguales, y llamarán 'isEqual:' para asegurarse de que son verdaderamente iguales en verdad. Esto permite una comparación muy rápida y la búsqueda del diccionario comparando solo los valores hash (que son solo enteros), y solo realiza una comparación real con 'isEqual:' cuando los hash son iguales. – AliSoftware

+0

Por ejemplo, para una cadena, uno puede implementar el método 'hash' devolviendo la longitud de la cadena. Dos cadenas que son iguales tendrán el mismo hash, y 2 cadenas diferentes tendrán diferentes valores de hash. Algunas cadenas que son diferentes (como '@" bar "' y '@" baz "') seguirán teniendo el mismo valor hash, pero eso no es un problema, en ese caso 'isEqual:' hará un análisis más profundo personaje para verificar la igualdad. Pero esta comparación (que toma más tiempo) solo se realizará para comparar cadenas de la misma longitud: una cadena con diferente longitud devolverá 'NO 'más rápidamente. – AliSoftware

1

la consistencia de esto es a través del Cacao (es decir, no indexofObject de NSArray: funciona de la misma?)

Es coherente y al mismo tiempo no lo es. Lo que quiero decir es que hay dos métodos que podrían usarse: isEqual y hash. No debe preocuparse demasiado por cuál se usa cuando. Lo que debe enfocarse es respetar los requisitos del protocolo NSObject y asegurarse de que si dos objetos son iguales de acuerdo con isEqual también tienen el mismo hash.

De los isEqual documentation in the NSObject Protocol Reference

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

+0

Dos comentarios: Uno, NSArray tiene un segundo método "indexOfObjectIdenticalTo:" que encuentra el _same_objeto, que es el mismo puntero de objeto. Dos objetos NSString * diferentes que contengan "foo" se considerarían diferentes. Dos, la implementación predeterminada de hash e isEqual: utiliza el puntero como la tecla hash y compara los punteros. Por ejemplo, NSWindow/UIWindow podría utilizarse como claves en un diccionario, y los punteros deberían ser idénticos. – gnasher729

Cuestiones relacionadas