Pregunta

Necesito determinar si un objeto está incluido en una relación de datos básicos para muchos (que es un NSSet), y estoy tratando de decidir cuál de las dos soluciones es mejor:

Solución 1)

if ([managedObject.items containsObject:itemOfInterest])
    return …

Solución 2)

for (NSManagedObject *item in managedObject.items)
    if ([item == itemOfInterest])
        return …

La solución 1 es más concisa, pero la clase de clase NSSet dice que la enumeración rápida funciona mejor que el Objectenumerator de NSSET. ¿También funciona mejor que contenSoBject?

¿Fue útil?

Solución

Siempre iría por la opción 1.

Es más conciso, puedo decir exactamente lo que está tratando de hacer con el código y es probable que el ContinSobject contenga algunas optimizaciones bastante ingeniosas.

Otros consejos

Ninguno de los dos. Deberías usar un NSFetchRequest con un predicado. Sus patrones pueden fallar accidentalmente toda la relación, lo cual es muy costoso y no es necesario solo para verificar si contiene un objeto. Hay formas de tener cuidado y no culpar a toda la relación, pero es frágil (los pequeños cambios en su búsqueda conducen a grandes cambios en el rendimiento), por lo que es mejor tener el hábito de usar NSFetchRequest en lugar de la colección para buscar. Me gusta establecer mi fetchLimit a 1 en estos casos, así que una vez que lo encuentra, deja de mirar.

Por conveniencia, es posible que desee crear un -containsFoo: Método en su objeto administrado para que no tenga que escribir la lógica de Fetch en todo el lugar.

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 personalizado isEqual: Lógica, estos pueden devolver diferentes resultados. Esto significa que la solución 2 podría ser un poco más rápida para las colecciones de datos no básicas, pero es porque en realidad está probando algo diferente, no por la enumeración de los objetos. (En realidad, esto solo es cierto para pequeñas colecciones; ver más abajo).

¿Por qué crees que la solución 1 usa -objectEnumerator?

Como @James Raybould señala, generalmente no debe intentar reescribir los métodos incorporados por razones de rendimiento. Si una isEqual: La versión de la solución 2 fue más rápida que la solución 1, ¿no crees que Apple habría implementado? -containsObject: ¿Usando el código en la solución 2?

En realidad, el subyacente CFSet se implementa como un hash, por lo que verificar la contención es logarítmico 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 ello en Cfset.c. Buscar CFSetContainsValue(). No se garantiza que la implementación de CFSET se mantenga igual, por supuesto, pero es útil para comprender cómo las preocupaciones de rendimiento generalmente se abordan dentro del cacao.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top