Si no puede obtener un objeto con objectAtIndex: de un NSSet, ¿cómo recupera los objetos?
objective-c
cocoa
cocoa-touch
object
nsset
ninja del nodo
fuente
fuente
[[nsSetObjects allObjects] objectAtIndex: anyInteger]
Respuestas:
Hay varios casos de uso para un conjunto. Puede enumerar (por ejemplo, con
enumerateObjectsUsingBlock
o NSFastEnumeration), llamarcontainsObject
para probar la membresía, usaranyObject
para obtener un miembro (no aleatorio) o convertirlo en una matriz (sin ningún orden en particular) conallObjects
.Un conjunto es apropiado cuando no desea duplicados, no le importa el orden y desea pruebas rápidas de membresía.
fuente
member:
mensaje al conjunto . Si regresanil
, el conjunto no contiene un objeto igual al que pasó; si devuelve un puntero de objeto, entonces el puntero que devuelve es al objeto que ya está en el conjunto. Los objetos del conjunto deben implementarhash
yisEqual:
para que esto sea útil.hash
las necesidades que deban aplicarse; iría mucho más rápido si lo hicieras.hash
protocolo NSObject: "Si dos objetos son iguales (según lo determinado por elisEqual:
método), deben tener el mismo valor hash". Actualmente, las implementaciones de NSObjecthash
yisEqual:
utilizan la identidad (dirección) del objeto. Si anulaisEqual:
, está configurando la posibilidad de objetos que no son idénticos pero sí iguales, que, si no anula tambiénhash
, seguirán teniendo valores hash diferentes. Eso viola el requisito de que los objetos iguales tengan valores hash iguales.member:
, el contenedor solo buscará en ese bucket (razón por la cual los conjuntos son mucho más rápidos que las matrices en las pruebas de membresía y los diccionarios son mucho más rápidos que las matrices paralelas en la búsqueda de valores clave). Si el objeto que se busca tiene el hash incorrecto, el contenedor buscará en el cubo incorrecto y no encontrará una coincidencia.-[NSObject hash]
era 0. Eso explica muchas cosas. = SNSSet no tiene un método objectAtIndex:
Intente llamar a allObjects que devuelve un NSArray de todos los objetos.
fuente
Es posible usar filterSetUsingPredicate si tiene algún tipo de identificador único para seleccionar el objeto que necesita.
Primero cree el predicado (asumiendo que su identificación única en el objeto se llama "identificador" y es un NSString):
Y luego elija el objeto usando el predicado:
fuente
NSArray *myArray = [myNSSet allObjects];
reemplace NSUInteger con el índice de su objeto deseado.
fuente
Para Swift3 y iOS10:
fuente
NSSet usa el método isEqual: (que los objetos que coloque en ese conjunto deben anular, además, el método hash) para determinar si un objeto está dentro de él.
Entonces, por ejemplo, si tiene un modelo de datos que define su singularidad mediante un valor de id (digamos que la propiedad es:
entonces implementaría isEqual: as
y podrías implementar hash:
Luego, puede obtener un objeto con esa ID (así como verificar si está en NSSet) con:
Pero sí, la única forma de obtener algo de un NSSet es considerando lo que define su singularidad en primer lugar.
No he probado qué es más rápido, pero evito usar la enumeración porque podría ser lineal, mientras que usar el método member: sería mucho más rápido. Esa es una de las razones para preferir el uso de NSSet en lugar de NSArray.
fuente
fuente
La mayoría de las veces no le importa obtener un objeto en particular de un conjunto. Le interesa probar para ver si un conjunto contiene un objeto. Para eso sirven los sets. Cuando desea ver si un objeto está en una colección, los conjuntos son mucho más rápidos que las matrices.
Si no le importa el objeto que obtenga, use el
-anyObject
que solo le dé un objeto del conjunto, como poner la mano en una bolsa y agarrar algo.Si le importa el objeto que obtiene, use el
-member
que le devuelva el objeto, o nil si no está en el conjunto. Necesita tener el objeto antes de llamarlo.Aquí hay un código que puede ejecutar en Xcode para comprender más
fuente