Der Grund, warum ==
funktioniert, ist der Zeigervergleich. Wenn Sie eine Konstante NSString
mit definieren@""
, eindeutigisiert der Compiler die Referenz. Wenn dieselben Konstanten an anderen Stellen in Ihrem Code definiert sind, zeigen sie alle auf dieselbe tatsächliche Position im Speicher.
Beim Vergleichen von NSString
Instanzen sollten Sie folgende isEqualToString:
Methode 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, die Sie benötigen initWithFormat
,
NSString *myString3 = [[NSString alloc] initWithFormat:@"foo"];
myString3
einen Zeiger auf die Konstante"foo"
, sodass im Allgemeinen alle drei Variablen auf denselben Speicherort verweisen. Dies gilt sowohl für gcc als auch für clang (mit Standardoptionen). Versuchen Sie dies zu kompilieren: gist.github.com/578568isEqual:
tatsächlich einen vollständigen Zeichenfolgenvergleich durch und gibt das gleiche Ergebnis zurück,isEqualToString
da in der NSObject-Protokollreferenz und der NSString-Klassenreferenz explizit angegeben wird: "Wenn zwei Objekte gleich sind-isEqual:
, müssen sie dasselbe haben." Hash-Wert "AND" Wenn zwei String-Objekte gleich sind (wie durch die Methode isEqualToString: bestimmt), müssen sie denselben Hash-Wert haben. "Der Gleichheitsoperator
==
vergleicht nur Zeigeradressen. Wenn Sie zwei identische Zeichenfolgen mithilfe der Literal-@""
Syntax erstellen, erkennt der Compiler, dass sie gleich sind, und speichert die Daten nur einmal. Daher zeigen die beiden Zeiger auf dieselbe Stelle. Auf andere Weise erstellte Zeichenfolgen können jedoch identische Daten enthalten, jedoch an unterschiedlichen Speicherorten gespeichert werden. Daher sollten Sie beim Vergleichen von Zeichenfolgen immer verwendenisEqual:
.Beachten Sie, dass
isEqual:
undisEqualToString:
immer den gleichen Wert zurückgeben, aberisEqualToString:
schneller ist.quelle
isEqualToString
: Verursacht eine Ausnahme, wenn der an ihn übergebene Parameter lautetnil
. Wenn es also eine Chance gibt, dass Sie mit einer Null-Zeichenfolge vergleichen, sollten Sie entweder zuerst eine Null-Prüfung durchführen oderisEqual:
==
vergleicht Speicherorte.ptr == ptr2
wenn beide auf denselben Speicherort zeigen. Dies funktioniert zufällig mit Zeichenfolgenkonstanten, da der Compiler zufällig eine tatsächliche Zeichenfolge für identische Zeichenfolgenkonstanten verwendet. Es funktioniert nicht , wenn Sie Variablen mit demselben Inhalt haben, da diese auf unterschiedliche Speicherorte verweisen. VerwendungisEqualToString
in einem solchen Fall.quelle
In Cocoa werden Zeichenfolgen mit der
isEqualToString:
Methode von NSString verglichen .Der Zeigervergleich funktioniert in Ihrem Fall, da der Compiler so sanft 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 nutzen.quelle
NSString
Instanzen mit identischem Inhalt erstellt:[NSMutableString string] != [NSMutableString string]
==
Funktionalität. Wenn Sie jedoch einen NSString löschen, einen Wert zuweisen und dann einen anderen NSString wie diesen löschenNSString stringWithFormat:
, erhalten Sie tatsächlich zwei verschiedene Zeichenfolgen, die==
fehlschlagen. Sie sagten, es gibt keine Garantie dafür, dass zwei NSString-Instanzen (nicht NSMutableString) eine NSString-Instanz gemeinsam nutzen, und ich habe einfach gefragt, ob Sie einen Beweis für diese Behauptung haben, damit ich sie gemeinsam nutzen kann.Ein Beispiel, das zeigt, wie der Adressvergleich als Ersatz für den Zeichenfolgenvergleich unterbrochen wird:
quelle
Schauen Sie sich dieses Beispiel an:
Daher verwendet der Compiler wahrscheinlich die isEqualToString-Methode, um isEquals für NSString- und Dereferenzierungszeiger zu verarbeiten, musste dies jedoch nicht. Und die Zeiger sind unterschiedlich, wie Sie sehen.
quelle
quelle