86 votes

Comprendre la comparaison NSString

Les deux comparaisons suivantes sont vraies:

1)

 @"foo" == @"foo";
 

2)

 NSString *myString1 = @"foo";
NSString *myString2 = @"foo";
myString1 == myString2;
 

Cependant, il est certain que, dans certains cas, deux NSString s ne peuvent pas être comparés à l'aide de l'opérateur d'égalité, et que [myString1 isEqualToString:myString2] est requis. Quelqu'un peut-il nous éclairer à ce sujet?

170voto

Jacob Relkin Points 90729

La raison pour laquelle == fonctionne est due à la comparaison de pointeur. Lorsque vous définissez une constante NSString aide de @"" , le compilateur désorganise la référence. Lorsque les mêmes constantes sont définies à d'autres endroits dans votre code, elles pointeront toutes vers le même emplacement réel en mémoire.

Lorsque vous comparez des instances NSString , vous devez utiliser la méthode isEqualToString: :

 NSString *myString1 = @"foo";
NSString *myString2 = @"foo";
NSString *myString3 = [[NSString alloc] initWithString:@"foo"];
NSLog(@"%d", (myString2 == myString3))  //0
NSLog(@"%d", (myString1 == myString2)); //1
NSLog(@"%d", [myString1 isEqualToString:myString2]); //1
NSLog(@"%d", [myString1 isEqualToString:myString3]); //1
[myString3 release];
 

13voto

David M. Points 2714

L'opérateur d'égalité, == compare uniquement pointeur d'adresses. Lorsque vous créez des chaînes identiques à l'aide de l'littérale @"" de la syntaxe, le compilateur détectera qu'ils sont égaux, et seulement de stocker les données une seule fois. Par conséquent, les deux pointeurs pointent vers le même emplacement. Cependant, les chaînes créées par d'autres moyens peuvent contenir des données identiques, pourtant, être stockés à différents emplacements de mémoire. Par conséquent, vous devriez toujours utiliser isEqual: lors de la comparaison des chaînes de caractères.

Notez que isEqual: et isEqualToString: retourne toujours la même valeur, mais isEqualToString: est plus rapide.

10voto

mipadi Points 135410

== compare les emplacements en mémoire. ptr == ptr2 s'ils pointent tous deux vers le même emplacement mémoire. Cela arrive à travailler avec des constantes de chaîne parce que le compilateur utilise une chaîne réelle pour des constantes de chaîne identiques. Cela ne fonctionnera pas si vous avez des variables avec le même contenu, car elles pointeront vers des emplacements de mémoire différents; utilisez isEqualToString dans un tel cas.

6voto

Nikolai Ruhe Points 45433

Dans Cocoa, les chaînes sont comparées selon la méthode isEqualToString: NSString.

La comparaison de pointeur fonctionne dans votre cas, car le compilateur est suffisamment souple pour fusionner les deux littéraux de chaîne afin qu'ils pointent vers un objet. Rien ne garantit que deux chaînes identiques partagent une instance NSString .

3voto

SK9 Points 9683

Un exemple démontrant comment la comparaison d'adresses en tant que substitut pour la comparaison de chaînes va casser:

     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSString *s1 = @"foo";
    NSString *s2 = @"foo";
    NSString *s3 = [[[NSString alloc] initWithString:@"foo"] autorelease];
    NSMutableString *s4 = [NSMutableString stringWithString:@"foobar"];
    [s4 replaceOccurrencesOfString:@"bar"
                        withString:@""
                           options:NSLiteralSearch
                             range:NSMakeRange(0, [s4 length])];

    NSLog(@"s1 = %p\n", s1);
    NSLog(@"s2 = %p\n", s2);
    NSLog(@"s3 = %p\n", s3);
    NSLog(@"s4 = %p\n", s4); // distinct from s1

    NSLog(@"%i", [s1 isEqualToString:s4]); // 1

    [pool release];
 

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