2011-03-02 15 views
15

He estado trabajando bajo la suposición de que NSSet usó hash para buscar coincidencias potenciales, y luego llamé a isEqual para cada una de ellas para verificar colisiones reales, pero me di cuenta de que no podía encontrar ninguna evidencia que respaldara esto.¿Utiliza NSSet hash para definir la exclusividad?

El motivo por el que lo menciono es la existencia del método "miembro:" en NSSet. ¿Por qué la documentación para miembros: se desvía de especificar que Equal: se usa para encontrar su objeto cuando nada más en NSSet lo hace? Does containsObject: solo usa el hash o algo?

¿Alguien puede confirmar este comportamiento? ¿E idealmente, documentación de referencia sobre esto?

Respuesta

17

Sugeriría leer Collections Programming Topics, específicamente la sección 'Conjuntos: Colecciones no ordenadas de objetos'. Allí se encuentra la siguiente información:

Esta información sobre el rendimiento asume implementaciones adecuadas para el método de hash definido para los objetos. Con una función de hash mala , el acceso y las ediciones toman tiempo lineal.

y

Los objetos en un conjunto deben responder a la NSObject conocer los protocolos de hash y IsEqual: (ver NSObject para obtener más información ). Si los objetos mutables se almacenan en un conjunto, ya sea el método de hash de los objetos no deben depender en el estado interno de los objetos mutables o los objetos mutables no debe ser modificado mientras están en el conjunto . Por ejemplo, un diccionario mutable se puede poner en un conjunto, pero no debe cambiarlo mientras está en allí. (Tenga en cuenta que puede ser difícil saber si un objeto dado está o no en una colección).

Por lo tanto, sí, hash y isEqual se usan como suponía.

+1

Debería haber mencionado que lo leí, así como la documentación relevante de NSSet. Sin embargo, si realmente lo lees, notarás que nunca dice nada sobre si se usa "isEqual", solo que los objetos deben implementarlo. Dado que debe implementar isEquals: si implementa hash, ese mismo consejo se aplicaría incluso si todo NSSet realmente utilizado fuera hash. Lo interesante es que solo advierten contra el hash y la mutabilidad. Si usaran Equal, uno pensaría que la misma advertencia se aplicaría allí. – DougW

12

Me gustaría intervenir y proporcionar más información sobre el uso de NSSet de hash y isEqual:, ya que he encontrado errores extraños recientemente y descubrí que se debían a que pasaban por alto hash.

Cuando almacena objetos personalizados en un conjunto, NSSet usa el valor devuelto por su método hash para agrupar objetos en distintas ubicaciones, en las que se comparan entre sí utilizando su método isEqual: respectivo. Entonces, básicamente, se llamará a hash en su objeto al insertar, construir, probar la membresía, etc., y si este objeto cae en un contenedor donde hay otros objetos, su método isEqual se usará para distinguirlo de ellos.

Es por eso que hash debe siempre ser lo mismo para objetos considerados iguales, y tanto como sea posible, ceda valores que distribuirán los objetos de manera uniforme. La última propiedad garantiza que los contenedores sean lo más pequeños posible, minimizando las llamadas al isEqual:.

+0

Información muy útil. Gracias. :) – Tiago

+0

Gracias por decir lo que la documentación no dice – felipeek

+0

¿Qué son los contenedores aquí? – BangOperator

Cuestiones relacionadas