wake-up-neo.com

Grundlegendes zum NSString-Vergleich

Die beiden folgenden Vergleiche werden als wahr bewertet:

1)

@"foo" == @"foo";

2)

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

Es gibt jedoch definitiv Zeiten, in denen zwei NSStrings nicht mit dem Gleichheitsoperator verglichen werden können, und [myString1 isEqualToString:myString2] ist stattdessen erforderlich. Kann jemand etwas Licht ins Dunkel bringen?

82
Yarin

Der Grund, warum == Funktioniert, ist der Zeigervergleich. Wenn Sie eine Konstante NSString mit @"" Definieren, macht der Compiler die Referenz eindeutig. Wenn dieselben Konstanten an anderen Stellen im Code definiert sind, verweisen sie alle auf dieselbe tatsächliche Position im Speicher.

Wenn Sie NSString Instanzen vergleichen, sollten Sie die Methode isEqualToString: Verwenden:

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

Bearbeiten:

NSString *myString3 = [[NSString alloc] initWithString:@"foo"]; 
// this is same with @"foo"

initWithString: Erstellt keine neue Referenz mehr, Sie benötigen initWithFormat,

NSString *myString3 = [[NSString alloc] initWithFormat:@"foo"];
162
Jacob Relkin

Der Gleichheitsoperator == Vergleicht nur Zeigeradressen. Wenn Sie zwei identische Zeichenfolgen mit der Literal-Syntax @"" Erstellen, erkennt der Compiler, dass sie gleich sind, und speichert die Daten nur einmal. Daher zeigen die beiden Zeiger auf dieselbe Position. Mit anderen Mitteln erstellte Zeichenfolgen können jedoch identische Daten enthalten, die jedoch an verschiedenen Speicherorten gespeichert sind. Daher sollten Sie immerisEqual: Zum Vergleichen von Zeichenfolgen verwenden.

Beachten Sie, dass isEqual: Und isEqualToString: Immer den gleichen Wert zurückgeben, aber isEqualToString: Ist schneller.

13
David M.

== vergleicht Positionen im Speicher. ptr == ptr2, wenn beide auf denselben Speicherort zeigen. Dies geschieht, um mit Zeichenfolgenkonstanten zu arbeiten, da der Compiler eins tatsächliche Zeichenfolge für identische Zeichenfolgenkonstanten verwendet. Es funktioniert nicht, wenn Sie Variablen mit demselben Inhalt haben, da diese auf unterschiedliche Speicherorte verweisen. Verwenden Sie in diesem Fall isEqualToString.

10
mipadi

In Cocoa werden Strings mit NSStrings isEqualToString: Methode.

Der Zeigervergleich funktioniert in Ihrem Fall, da der Compiler so intelligent ist, dass die beiden Zeichenfolgenliterale zusammengeführt werden, um auf ein Objekt zu verweisen. Es gibt keine Garantie dafür, dass zwei identische Zeichenfolgen eine NSString -Instanz gemeinsam haben.

6
Nikolai Ruhe

Ein Beispiel, das zeigt, wie der Adressvergleich als Ersatz für den Zeichenfolgenvergleich funktioniert:

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

Schauen Sie sich dieses Beispiel an:

NSString *myString1 = @"foo";
NSMutableString *myString2 = [[NSMutableString stringWithString:@"fo"] stringByAppendingString: @"o"];

NSLog(@"isEquality: %@", ([myString1 isEqual:myString2][email protected]"+":@"-")); //YES
NSLog(@"isEqualToStringity: %@", ([myString1 isEqualToString:myString2][email protected]"+":@"-")); //YES
NSLog(@"==ity: %@", ((myString1 == myString2)[email protected]"+":@"-")); // NO

Daher verwendet der Compiler wahrscheinlich die Methode isEqualToString, um isEquals für NSString- und Dereferenzierungszeiger zu verarbeiten, obwohl dies nicht erforderlich war. Und die Zeiger sind anders, wie Sie sehen.

0
Dmitry Zvorikin