¿Cuál es el NSObject IsEqual: y la función de hash por defecto?
-
12-09-2019 - |
Pregunta
Tengo una clase de modelo de base de datos que es un NSObject
. Tengo un conjunto de estos objetos en un NSMutableArray
. Yo uso indexOfObject:
para encontrar una coincidencia. El problema es que los cambios de dirección de memoria del modelo de objetos. Así que estoy reemplazando el método hash
para devolver el modelo de identificador de fila. Sin embargo, esto no lo arregla. También tengo que reemplazar el método isEqual:
para comparar el valor del método hash
.
¿Qué hace el uso del método isEqual:
para determinar la igualdad de forma predeterminada?
Estoy asumiendo que utiliza la dirección de memoria. Después de leer el documentación isEqual:
pensé que utiliza el valor del método hash
. Obviamente, esto no es el caso ya que mi intento de anular ese valor no solucionar mi problema inicial.
Solución
Como has adivinado correctamente, el comportamiento por defecto de NSObject
isEqual:
está comparando la dirección de memoria del objeto. Curiosamente, esto no está actualmente documentada en el NSObject Referencia de la Clase , pero se documenta en el documentación introspección , que establece:
La aplicación por defecto de
NSObject
isEqual:
simplemente comprueba por la igualdad puntero.
Por supuesto, ya que son sin duda conscientes, subclases de NSObject
puede anular isEqual:
a comportarse de manera diferente. Por ejemplo, el método de NSString
isEqual:
, cuando pasa a otra NSString
, en primer lugar comprobar la dirección y luego comprobar si hay una coincidencia literal exacta entre las cuerdas.
Otros consejos
La respuesta acerca de la aplicación por defecto de isEqual:
es uno integral. Así que sólo añadir mi nota sobre la aplicación por defecto de hash
. Aquí está:
-(unsigned)hash {return (unsigned)self;}
es decir que es sólo el mismo valor del puntero que se utiliza en isEqual:
. Así es como se puede comprobar esto:
NSObject *obj = [[NSObject alloc] init];
NSLog(@"obj: %@",obj);
NSLog(@"hash: %x",obj.hash);
El resultado será algo como esto:
obj: <NSObject: 0x16d44010>
hash: 16d44010
Saludos.
Por cierto, en iOS 8 hash
convirtió no una propiedad de un método, pero está ahí.
Me gustaría asumir que NSObject
isEquals
utiliza el operador ==
y hash
utiliza la dirección de memoria.
método isEquals
nunca debe hash
utiliza como una prueba absoluta de la igualdad. Está garantizado para tener dos objetos que tienen hashCode
similares, si la búsqueda de suficientes objetos (basta con crear más de 2 ^ 32 objetos diferentes, y por lo menos dos de ellos tendrá el mismo hash
).
En otras palabras, hash
requiere la especificación siguiente: si dos objetos son iguales, entonces su hash
tiene que ser igual; sin embargo, si los valores hash
dos objetos son iguales, no son necesariamente iguales.
Como consejo, siempre se debe anular isEquals
y hashCode
juntos.