Si vous ne pouvez pas obtenir un objet avec objectAtIndex: à partir d'un NSSet, comment récupérer des objets?
objective-c
cocoa
cocoa-touch
object
nsset
noeud ninja
la source
la source
[[nsSetObjects allObjects] objectAtIndex: anyInteger]
Réponses:
Il existe plusieurs cas d'utilisation pour un ensemble. Vous pouvez énumérer via (par exemple avec
enumerateObjectsUsingBlock
ou NSFastEnumeration), appelercontainsObject
pour tester l'appartenance, utiliseranyObject
pour obtenir un membre (non aléatoire) ou le convertir en un tableau (sans ordre particulier) avecallObjects
.Un ensemble est approprié lorsque vous ne voulez pas de doublons, que vous ne vous souciez pas de la commande et que vous voulez des tests d'adhésion rapides.
la source
member:
message à l'ensemble . S'il retournenil
, l'ensemble ne contient pas un objet égal à celui que vous avez passé; s'il renvoie un pointeur d'objet, alors le pointeur qu'il renvoie est vers l'objet déjà dans l'ensemble. Les objets de l'ensemble doivent implémenterhash
etisEqual:
pour que cela soit utile.hash
nécessaire de l'implémenter; cela irait beaucoup plus vite si vous faisiez cela.hash
dans le protocole NSObject: «Si deux objets sont égaux (comme déterminé par laisEqual:
méthode), ils doivent avoir la même valeur de hachage.» Actuellement, les implémentations de NSObjecthash
etisEqual:
utilisent l'identité (adresse) de l'objet. Si vous remplacezisEqual:
, vous configurez la possibilité d'objets qui ne sont pas identiques mais égaux - qui, si vous ne remplacez pas égalementhash
, auront toujours des hachages différents. Cela viole l'exigence selon laquelle les objets égaux ont des hachages égaux.member:
, le conteneur ne recherchera que dans celui-là bucket (c'est pourquoi les ensembles sont tellement plus rapides que les tableaux lors des tests d'appartenance et les dictionnaires sont tellement plus rapides que les tableaux parallèles lors de la recherche clé-valeur). Si l'objet recherché a le mauvais hachage, le conteneur recherchera dans le mauvais compartiment et ne trouvera pas de correspondance.-[NSObject hash]
était 0. Cela explique beaucoup de choses. = SNSSet n'a pas de méthode objectAtIndex:
Essayez d'appeler allObjects qui renvoie un NSArray de tous les objets.
la source
il est possible d'utiliser filteredSetUsingPredicate si vous avez une sorte d'identifiant unique pour sélectionner l'objet dont vous avez besoin.
Commencez par créer le prédicat (en supposant que votre identifiant unique dans l'objet s'appelle "identifiant" et qu'il s'agit d'une NSString):
Et puis choisissez l'objet en utilisant le prédicat:
la source
NSArray *myArray = [myNSSet allObjects];
remplacez NSUInteger par l'index de l'objet souhaité.
la source
Pour Swift3 et iOS10:
la source
NSSet utilise la méthode isEqual: (que les objets que vous placez dans cet ensemble doivent remplacer, en outre, la méthode de hachage) pour déterminer si un objet se trouve à l'intérieur de celui-ci.
Ainsi, par exemple, si vous avez un modèle de données qui définit son unicité par une valeur d'id (disons que la propriété est:
alors vous implémenteriez isEqual: as
et vous pouvez implémenter le hachage:
Ensuite, vous pouvez obtenir un objet avec cet ID (ainsi que vérifier s'il est dans le NSSet) avec:
Mais oui, la seule façon d'obtenir quelque chose d'un NSSet est de considérer ce qui définit son unicité en premier lieu.
Je n'ai pas testé ce qui est le plus rapide, mais j'évite d'utiliser l'énumération car cela pourrait être linéaire alors que l'utilisation de la méthode member: serait beaucoup plus rapide. C'est l'une des raisons de préférer l'utilisation de NSSet au lieu de NSArray.
la source
la source
La plupart du temps, vous ne vous souciez pas d'obtenir un objet particulier d'un ensemble. Vous vous souciez de tester pour voir si un ensemble contient un objet. C'est à cela que servent les décors. Lorsque vous voulez voir si un objet est dans une collection, les ensembles sont beaucoup plus rapides que les tableaux.
Si vous ne vous souciez pas de ce qui obtenez vous opposez, utilisez ce
-anyObject
qui vous donne un seul objet de l'ensemble, comme mettre la main dans un sac et saisissant quelque chose.Si vous vous souciez de l'objet que vous obtenez, utilisez celui
-member
qui vous rend l'objet, ou nul s'il n'est pas dans l'ensemble. Vous devez déjà disposer de l'objet avant de l'appeler.Voici un code que vous pouvez exécuter dans Xcode pour en savoir plus
la source