Noções básicas sobre comparação NSString

Ambas as comparações a seguir são avaliadas como verdadeiras:

1)

@"foo" == @"foo"; 

2)

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

No entanto, há definitivamente momentos em que dois NSString s não podem ser comparados usando o operador de igualdade e [myString1 isEqualToString:myString2] é necessário em vez disso. Alguém pode lançar alguma luz sobre isto?

A razão pela qual == funciona é por causa da comparação de pointers. Quando você define um NSString constante usando @"" , o compilador unifica a referência. Quando as mesmas constantes são definidas em outros lugares em seu código, todas apontarão para a mesma localização real na memory.

Ao comparar as instâncias do NSString , você deve usar o método 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]; 

O operador de igualdade == compara apenas endereços de ponteiro. Quando você cria duas cadeias idênticas usando a syntax literal @"" , o compilador detectará que elas são iguais e armazenará os dados apenas uma vez. Portanto, os dois pointers apontam para o mesmo local. No entanto, as strings criadas por outros meios podem conter dados idênticos, ainda que sejam armazenadas em locais de memory diferentes. Portanto, você deve sempre usar isEqual: ao comparar strings.

Observe que isEqual: e isEqualToString: sempre retorna o mesmo valor, mas isEqualToString: é mais rápido.

== compara locais na memory. ptr == ptr2 se ambos apontarem para o mesmo local de memory. Isso acontece ao trabalhar com constantes de string porque o compilador usa uma string real para constantes de string idênticas. Não funcionará se você tiver variables ​​com o mesmo conteúdo, porque elas apontarão para locais de memory diferentes; use isEqualToString em tal caso.

Em seqüências de caracteres de cacau são comparadas usando isEqualToString: método do NSString.

Comparação de ponteiro funciona no seu caso porque o compilador é gentil o suficiente para mesclar os dois literais de seqüência de caracteres para apontar para um object. Não há garantia de que duas cadeias idênticas compartilhem uma instância do NSString .

Um exemplo que demonstra como a comparação de endereços como um substituto para a comparação de cadeias será interrompida:

  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]; 

Confira este exemplo:

 NSString *myString1 = @"foo"; NSMutableString *myString2 = [[NSMutableString stringWithString:@"fo"] stringByAppendingString: @"o"]; NSLog(@"isEquality: %@", ([myString1 isEqual:myString2]?@"+":@"-")); //YES NSLog(@"isEqualToStringity: %@", ([myString1 isEqualToString:myString2]?@"+":@"-")); //YES NSLog(@"==ity: %@", ((myString1 == myString2)?@"+":@"-")); // NO 

Portanto, é provável que o compilador use o método isEqualToString para processar isEquals para os pointers de referência e cancelamento de referência, embora não devesse. E os pointers são diferentes, como você vê.

  NSString *str1=[NSString stringWithFormat:@"hello1"]; NSString *str2=[NSString stringWithFormat:@"hello1"]; NSString *str3 = [[NSString alloc] initWithString:@"hello1"]; // == compares the pointer but in our example we are taking same string value to different object using @ so it will point to same address so output will be TRUE condition if (str1==str2) { NSLog(@"Both String are equal"); } else{ NSLog(@"Both String not are equal"); } // == compares the pointer but in our example we are taking same string value to different object but we have allocated different string so both object will pount to different address so output will be FALSE condition if (str1==str3) { NSLog(@"Both String are equal"); } else{ NSLog(@"Both String not are equal"); } // compare:= compares the values of objects so output will be TRUE condition if ([str1 compare:str3]== NSOrderedSame) { NSLog(@"Both String are equal"); } else{ NSLog(@"Both String not are equal"); } // isEqual compares the values of objects so output will be TRUE condition if ([str1 isEqual:str2]) { NSLog(@"Both String are equal"); } else{ NSLog(@"Both String not are equal"); } // isEqual compares the values of objects so output will be TRUE condition if ([str1 isEqual:str3]) { NSLog(@"Both String are equal"); } else{ NSLog(@"Both String not are equal"); } // isEqualToString compares the values of objects so output will be TRUE condition if ([str1 isEqualToString:str2]) { NSLog(@"Both String are equal"); } else{ NSLog(@"Both String not are equal"); } // isEqualToString compares the values of objects so output will be TRUE condition if ([str1 isEqualToString:str3]) { NSLog(@"Both String are equal"); } else{ NSLog(@"Both String not are equal"); } // == compares the pointers since we have initialized the same value to first object so the pointer be be same for same value so output will be TRUE condition if (str1==@"hello1") { NSLog(@"Both String are equal"); } else{ NSLog(@"Both String not are equal"); }