Frage

I ' m learning objective-C und Cocoa und haben sich über diese Aussage:

Die Cocoa-frameworks erwarten, dass die Globale string-Konstanten anstelle von string-Literale verwendet werden für dictionary keys, Benachrichtigung und Ausnahme-Namen, und einige Parameter der Methode, die nehmen strings.

Ich habe nur gearbeitet, in höheren Sprachen so noch nie gehabt haben zu prüfen, die details von strings, die viel.Was ist der Unterschied zwischen ein string-Konstanten und string-literal?

War es hilfreich?

Lösung

In Objective-C, die syntax @"foo" ist ein unveränderlich, literal Instanz von NSString.Es nicht eine Konstante Zeichenkette aus einem string-literal als Mike angenommen.

Objective-C-Compiler in der Regel do intern Literale Zeichenfolgen innerhalb compilation-Einheiten — das heißt, Sie verschmelzen mehrere Verwendungen des gleichen literal string — und es ist möglich, für den linker, um eine zusätzliche Praktikum über die Zusammenstellung Einheiten, die unmittelbar in ein single binary.(Da Kakao unterscheidet zwischen veränderlichen und unveränderlichen strings und Zeichenketten sind immer auch unveränderliche, kann dies einfach und sicher.)

Konstante Streicher auf der anderen Seite sind in der Regel deklariert und definiert, wie diese:

// MyExample.h - declaration, other code references this
extern NSString * const MyExampleNotification;

// MyExample.m - definition, compiled for other code to reference
NSString * const MyExampleNotification = @"MyExampleNotification";

Der Punkt der syntaktischen übung hier ist, dass Sie machen können verwendet von der string effizienter, indem sichergestellt wird, dass es nur eine Instanz der Zeichenfolge verwendet auch über mehrere frameworks (shared libraries) in den gleichen Adressraum.(Die Platzierung der const Stichwort Angelegenheiten;es garantiert, dass der Zeiger selbst ist garantiert Konstante.)

Beim brennen von Speicher ist nicht so groß einen deal, wie es möglicherweise gewesen, in den Tagen von 25MHz 68030-workstations mit 8MB RAM, vergleichen von strings auf Gleichheit kann einige Zeit dauern.Sicherstellung, dass die meisten der Zeit, die Zeichenfolgen gleich sind, werden auch die Zeiger-gleich hilft.

Sagen, zum Beispiel, Sie wollen zu abonnieren, Benachrichtigungen von einem Objekt mit Namen.Wenn Sie mit nicht-Konstanten-strings für die Namen, die NSNotificationCenter Veröffentlichung der Meldung könnte wind-up tun eine Menge von byte-by-byte-string-Vergleiche bei der Bestimmung, wer ist daran interessiert.Wenn die meisten dieser Vergleiche sind kurzgeschlossen, weil die strings, die verglichen werden, haben den gleichen Zeiger, kann das ein großer Gewinn.

Andere Tipps

Einige Definitionen

Ein literal ist ein Wert, der per definition unveränderlich.zB: 10
Ein Konstante ist eine nur-lese-variable oder Zeiger.zB: const int age = 10;
Ein string-literal ein Ausdruck wie @"".Der compiler ersetzt diesen mit einer Instanz von NSString.
Ein string-Konstante ist eine nur-lese-Zeiger um NSString.zB: NSString *const name = @"John";

Einige Kommentare in der letzten Zeile:

  • Das ist ein konstanter Zeiger, nicht ein konstantes Objekt1. objc_sendMsg2 egal, ob Sie qualifiziert sind, das Objekt mit const.Wenn Sie möchten, dass ein unveränderliches Objekt, müssen Sie code, der Unveränderlichkeit im inneren des Objekts3.
  • Alle @"" Ausdrücke werden in der Tat unveränderlich.Sie werden ersetzt4 bei der Kompilierung mit den Instanzen NSConstantString, die eine spezielle Unterklasse von NSString mit einem festen Speicher-layout5.Dies erklärt auch, warum NSString das einzige Objekt, das können initialisiert werden zur compile-Zeit6.

Ein konstanter string würde const NSString* name = @"John"; das ist äquivalent zu NSString const* name= @"John";.Hier die syntax und Programmierer Absicht falsch sind: const <object> wird ignoriert, und die NSString Instanz (NSConstantString) wurde bereits unveränderlich.

1 Keyword const gilt, gilt für Sie, was ist sofort zu seiner linken.Wenn es nichts gibt, zu seiner linken, es gilt das, was unmittelbar zu Ihrer rechten.

2 Dies ist die Funktion, die zur Laufzeit verwendet, zu senden Sie alle Nachrichten in Objective-C, und daher, was Sie ändern können, die den Zustand eines Objekts.

3 Beispiel:in const NSMutableArray *array = [NSMutableArray new]; [array removeAllObjects]; const kann nicht verhindern, dass die Letzte Anweisung.

4 Der LLVM-code, mit dessen Hilfe die Ausdruck RewriteModernObjC::RewriteObjCStringLiteral in RewriteModernObjC.cpp.

5 Sehen NSConstantString definition, cmd+klicken Sie in Xcode.

6 Erstellen compile-Zeit Konstanten für andere Klassen leicht sein würde, aber es würde erfordern, dass der compiler verwenden eine spezielle Unterklasse.Dies würde die Kompatibilität mit älteren Objective-C-Versionen.


Zurück zu Ihrem Angebot

Die Cocoa-frameworks erwarten, dass die Globale string-Konstanten statt string-Literale sind verwendet für dictionary keys, Benachrichtigung und Ausnahme-Namen, und einige Parameter der Methode, die nehmen strings.Sie sollte immer bevorzugen, string-Konstanten über string-Literale, wenn Sie eine Wahl haben.Mit Hilfe von string-Konstanten, die Sie gewinnen die Hilfe von der compiler überprüfen Sie Ihre Rechtschreibung und damit die Vermeidung von Laufzeitfehlern.

Es sagt, dass Literale sind fehleranfällig.Aber es heißt nicht, dass Sie auch langsamer.Vergleichen Sie:

// string literal
[dic objectForKey:@"a"];

// string constant
NSString *const a = @"a";
[dic objectForKey:a];

Im zweiten Fall bin ich mit den Tasten mit const-Zeigern, also statt [a isEqualToString:b], Kann ich tun (a==b).Die Umsetzung isEqualToString: vergleicht den Hashwert und dann läuft die C-Funktion strcmp, so es ist langsamer als Vergleich der Zeiger direkt.Die warum Konstante strings sind besser: Sie sind schneller zu vergleichen und weniger anfällig für Fehler.

Möchten Sie auch Ihre Konstante string, der globalen, tun Sie es, wie diese:

// header
extern NSString *const name;
// implementation
NSString *const name = @"john";

Wir verwenden C++, da meine Objective-C ist völlig nicht-existent.

Wenn Sie stash eine Zeichenfolge in eine Konstante variable:

const std::string mystring = "my string";

Nun, wenn Sie Methoden aufrufen, die Sie verwenden my_string, bist du mit einer string-Konstante:

someMethod(mystring);

Oder, Sie können rufen Sie diese Methoden mit dem string-literal direkt:

someMethod("my string");

Der Grund ist vermutlich, dass Sie Sie ermutigen, die Verwendung von string-Konstanten ist, da Objective-C nicht tun "Praktikum";das heißt, wenn Sie die gleiche string-literal in mehreren stellen, dass es tatsächlich einen anderen Zeiger auf eine separate Kopie der Zeichenfolge.

Für dictionary keys macht einen riesigen Unterschied, denn wenn ich die beiden Zeiger zeigen auf die gleiche Sache, das ist sehr viel günstiger als einen ganzen string-Vergleich zu machen Sie sicher, dass die Saiten den gleichen Wert hat.

Edit: Mike, in C# Zeichenfolgen sind unveränderlich, und Literale Zeichenfolgen mit identischen Werten am Ende alle zeigen auf den gleichen string-Wert.Ich kann mir vorstellen, dass gilt auch für andere Sprachen, die unveränderliche Zeichenketten.In Ruby, die veränderbare strings, bieten Sie eine neue Daten-Typ:Symbole ("foo" vs.:foo, wo die erstere ist eine veränderbare Zeichenfolge, und die letztere ist eine unveränderliche Kennung Häufig verwendet, für die Hash-Schlüssel).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top