75 votes

Vérifier si une instance de NSString est contenue dans un NSArray.

J'ai un tableau contenant un certain nombre de chaînes de caractères et je veux vérifier si une certaine chaîne est contenue dans le tableau. Si j'utilise la fonction containsObject : message sur le tableau, j'obtiens des résultats corrects. Est-ce que tous les NSString Les objets ayant la même chaîne de caractères pointent vers le même objet ? Ou pourquoi la containsObject Travailler ?

NSArray *stringArray = [NSArray arrayWithObjects:@"1",@"2",@"3",anotherStringValue, nil];
if([stringArray containsObject:@"2"]){
  //DO SOMETHING
}

168voto

Regexident Points 17722

Oui, les NSStrings (chaînes littérales) codées en dur (c'est-à-dire tout @"..." dans votre code source) sont transformées en chaînes de caractères qui existent indéfiniment pendant l'exécution de votre processus.

Cependant NSArray 's containsObject: appels de méthodes isEqual: sur ses objets, d'où même une chaîne créée dynamiquement comme [NSString stringWithFormat:@"%d", 2] rendrait YES dans votre exemple de code.
C'est parce que l'élément NSString isEqual: (ou plus précisément son isEqualToString: ) est mise en œuvre pour être connaissance du contenu (par opposition à la comparaison des identités des pointeurs) et renvoie donc YES pour toute paire de chaînes de caractères contenant la même séquence de caractères (au moment de la comparaison), peu importe comment et quand elles ont été créées.

Pour vérifier l'identité des pointeurs, il faut énumérer les tableaux et les comparer par l'intermédiaire de

NSString *yourString = @"foo";
BOOL identicalStringFound = NO;
for (NSString *someString in stringArray) {
    if (someString == yourString) {
        identicalStringFound = YES;
        break;
    }
}

(ce que vous ne voudriez probablement pas, cependant).

Ou d'une manière plus pratique :

BOOL identicalStringFound = [stringArray indexOfObjectIdenticalTo:someString] != NSNotFound;

(vous ne voudriez probablement pas de celle-ci non plus).


En résumé :

Donc la raison pour laquelle vous avez une réponse positive de containsObject: es PAS car les chaînes littérales partagent la même instance de constante, MAIS parce que containsObject: par des appels de convention isEqual: qui est conscient du contenu.

Vous pouvez lire la documentation (succincte) de l'application isEqual: de la Protocole NSObject .

17voto

ughoavgfhw Points 28400

containsObject: effectue une vérification de la valeur, et non du pointeur. Il utilise le isEqual: définie par NSObject et surchargée par d'autres objets pour les tests. Par conséquent, si deux chaînes de caractères contiennent la même séquence de caractères, elles seront considérées comme identiques.

La distinction entre le test des pointeurs et le test des valeurs est très importante dans certains cas. Les chaînes constantes définies dans le code source sont combinées par le compilateur de sorte qu'elles constituent le même objet. Cependant, les chaînes de caractères créées dynamiquement ne sont pas le même objet. Voici un exemple de programme qui le démontre :

int main(int argc, char **argv) {
    NSAutoreleasePool *p = [NSAutoreleasePool new];
    NSString *constantString = @"1";
    NSString *constantString2 = @"1";
    NSString *dynamicString = [NSString stringWithFormat:@"%i",1];
    NSArray *theArray = [NSArray arrayWithObject:constantString];
    if(constantString == constantString2) NSLog(@"constantString == constantString2");
        else NSLog(@"constantString != constantString2");
    if(constantString == dynamicString) NSLog(@"constantString == dynamicString");
        else NSLog(@"constantString != dynamicString");
    if([constantString isEqual:dynamicString]) NSLog(@"[constantString isEqual:dynamicString] == YES");
        else NSLog(@"[constantString isEqual:dynamicString] == NO");
    NSLog(@"theArray contains:\n\tconstantString: %i\n\tconstantString2: %i\n\tdynamicString: %i",
          [theArray containsObject:constantString],
          [theArray containsObject:constantString2],
          [theArray containsObject:dynamicString]);
}

La sortie de ce programme est :

2011-04-27 17:10:54.686 a.out[41699:903] constantString == constantString2
2011-04-27 17:10:54.705 a.out[41699:903] constantString != dynamicString
2011-04-27 17:10:54.706 a.out[41699:903] [constantString isEqual:dynamicString] == YES
2011-04-27 17:10:54.706 a.out[41699:903] theArray contient :
constanteString : 1
constanteString2 : 1
dynamicString : 1

5voto

isuru Points 879

Vous pouvez utiliser containsObject pour savoir si une certaine chaîne existe,

NSArray *stringArray = [NSArray arrayWithObjects:@"1",@"2",@"3",anotherStringValue, nil];

if ( [stringArray containsObject: stringToFind] ) {
    // if found
} else {
    // if not found
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X