Ninguno. Debe usar un NSFetchRequest
con un predicado. Sus patrones pueden fallar accidentalmente en toda la relación, lo cual es muy costoso y no es necesario solo para verificar si contiene un objeto. Hay maneras de ser cuidadoso y no culpar a toda la relación, pero es frágil (pequeños cambios en su búsqueda conducen a grandes cambios en el rendimiento) y, por lo tanto, es mejor tener el hábito de usar NSFetchRequest
en lugar de la colección para buscar. Me gusta establecer mi fetchLimit
en 1 en estos casos, así que una vez que lo encuentra, deja de buscar.
Para su conveniencia, es posible que desee crear un método -containsFoo:
en su objeto administrado para que no tenga que escribir la lógica de búsqueda por todos lados.
Sus dos soluciones anteriores son sutilmente diferentes. El primero prueba si hay un objeto en la colección que isEqual:
a itemOfInterest
. Su segunda solución prueba si hay un objeto en la colección en la misma ubicación de memoria que itemOfInterest
. Para objetos con lógica personalizada isEqual:
, estos pueden arrojar resultados diferentes. Esto significa que la solución 2 podría ser un poco más rápida para colecciones de datos no centrales, pero es porque en realidad está probando algo diferente, no debido a la enumeración de objetos. (En realidad, esto solo es válido para colecciones pequeñas; consulte a continuación.)
¿Por qué cree que la solución 1 usa -objectEnumerator
?
Como lo señala @James Raybould, generalmente no debe intentar reescribir los métodos integrados por motivos de rendimiento. Si una versión isEqual:
de la Solución 2 fuera más rápida que la Solución 1, ¿no crees que Apple hubiera implementado -containsObject:
usando el código en la solución 2?
En realidad, el CFSet
subyacente se implementa como un hash, por lo que la comprobación de la contención es logarítmica en lugar de lineal. En términos generales, para conjuntos grandes con funciones hash razonables, la solución 1 será más rápida. Vea el código para él en CFSet.c. Busque CFSetContainsValue()
. No está garantizado que la implementación de CFSet siga siendo la misma, por supuesto, pero es útil para entender cómo las preocupaciones sobre el rendimiento generalmente se abordan en Cocoa.
Me puede estar perdiendo algo aquí, pero ¿por qué necesita buscar en absoluto? Si ya tiene ambos objetos en cada lado de una relación, ya tiene la información que necesita. ¿Es esta una relación de muchos a muchos o uno a muchos sin reciprocidad? – TechZen
@TechZen: se realiza una búsqueda por criterio de búsqueda del usuario. Los resultados se muestran en una tabla.El usuario realiza una subselección de estos resultados a través de la tabla. Hay otra tabla con miembros de la relación de muchos, presentada con casillas de verificación. Los estados de la casilla de verificación se deben establecer según si todos, ninguno o algunos de los objetos seleccionados contienen su elemento. Puede haber muchos objetos involucrados, por lo que es importante usar el método más eficiente. Gracias al consejo de los Sres. Raybould y Napier, estoy seguro de que containsObject es el camino a seguir. – Wienke