2009-05-25 5 views
8

Ich habe in mehreren Büchern gelesen ... und online ... über unveränderliche und veränderbare Zeichenfolgen. Sie behaupten "unveränderliche Zeichenfolgen" können nicht geändert werden. (Aber sie definieren nie "ändern".)Das letzte Wort auf NSStrings: Veränderbar und unveränderlich

Welche dieser NSStrings konnte ohne Verwendung von NSMutableString geändert werden?

Die Zeichenfolge enthält "Wels" ... und später versuche ich, es in "Katze" zu ändern. (Gleiche Buchstaben, nur kürzer.)

Es enthält "Katze" ... und ich versuche, es zu "Wels" zu ändern. (Ähnliche starten ... aber nur länger gemacht.)

Ich ändere "Katze" in "CAT". (Gleiche Buchstaben, aber nur der Fall hat sich geändert.)

Ich ändere "Katze" in "Hund". (Völlig andere Zeichenfolge, aber die gleiche Länge.)

Ich ändere "Katze" in "Hartriegel". (Völlig andere Zeichenfolge, aber länger.)

+0

Fast eine clintonische Frage! –

Antwort

20

Die Antwort ist - keine. Unveränderlich bedeutet, dass es nicht in irgendetwas anders als die ursprüngliche Zeichenfolge geändert werden kann. Jedes Zeichen bleibt gleich, die Länge kann nicht geändert werden usw. Sobald es definiert ist, können Sie an dieser Zeichenfolge nichts ändern. Wenn Sie es länger oder kürzer machen oder eines der Zeichen ändern möchten, müssen Sie eine neue Zeichenfolge erstellen (oder verwenden Sie zunächst einen NSMutableString).

+0

Danke für die schnelle Antwort. Macht das NSString nicht ziemlich nutzlos? Ich setze ein * VARIABLE * auf einen NSString-Wert ... und dann kann ich es nie ändern. Wird das nicht in anderen Sprachen als "Konstante" bezeichnet? Ich möchte (stattdessen) wahrscheinlich "etwas tun" mit meinen Stichen 99% der Zeit. Also sollte ich MSMutableString nicht fast überall verwenden? (Aber ich sehe selten, dass es verwendet wird, verglichen mit dem SEHR häufig verwendeten NSString.) – Donna

+0

Stellen Sie sich vor, wenn int/float/long ebenfalls immutable wären. int x = 5; und dann x kann * NIE * geändert werden. Unveränderlich ist (fast) nutzlos. Nein? – Donna

+0

"etwas tun" bedeutet möglicherweise, sie aus einem Datenspeicher auszulesen und anzuzeigen. In diesem Fall werden Sie sie nicht ändern wollen. – rein

2

Sie müssen „change“ definieren, auch :)

Grundsätzlich, wenn Sie ein NSString erstellen, werden Sie eine Reihe von Zeichen zu schaffen und Sie sagen dem Compiler, der den Inhalt vonder Anordnung wird sich nie ändern. Der Teil "niemals ändern" ist der "unveränderliche" Teil; Die Daten, die die Zeichenfolge enthält, können niemals geändert werden.

Auf der anderen Seite können Sie mit einem NSMutableString tatsächlich die Daten ändern, auf die es zeigt (daher ist es "veränderbar"). Beachten Sie die 'appendString' -Methode, die für NSMutableString vorhanden ist; Dies nimmt tatsächlich Daten und schlägt sie auf das Ende der Zeichenfolge.

Zum Beispiel, wenn Sie hatte:

NSString * MyString = @ "Katze"; myString = @ "Goldfisch";

Das würde gut funktionieren. Sie ändern niemals wirklich die Daten, die myString enthält; Sie sagen einfach, dass Sie auf ein neues Segment unveränderbarer Daten zeigen möchten.

Die einzige Zeit, in der Sie tatsächlich Probleme mit den Unterschieden zwischen veränderbaren und unveränderlichen Objekten bekommen würden, ist, wenn Sie tatsächlich versuchen, myString direkt zu modifizieren (z. B. append "s sind cool" oder etwas).

Mit anderen Worten, jede Klasse würde Ihnen erlauben, eine beliebige Zeichenfolge in eine andere Zeichenfolge zu "ändern", aber die Methoden, die Sie dafür verwenden, wären sehr unterschiedlich. Um beispielsweise "cat" mit einer veränderbaren Zeichenfolge in "CAT" umzuwandeln, können Sie jedes Zeichen durchlaufen und es einfach in Großbuchstaben schreiben (da Sie den Inhalt einer veränderbaren Zeichenfolge ändern können). Bei einer unveränderlichen Zeichenfolge müssten Sie andererseits zuerst die ursprüngliche Zeichenfolge kopieren, ändern und dann die Variable so umleiten, dass sie auf diesen neuen NSString verweist.

Die folgenden Links könnten nützlich sein: http://www.kirupa.com/forum/showthread.php?t=307928 http://forums.macrumors.com/showthread.php?t=467099

ich auch einige googeln würde empfehlen, tun; Das ist eine Frage, die sich auf die Entwicklung im Allgemeinen bezieht, und es ist ein relativ wichtiger Begriff, den es zu erfassen gilt. Es wurde auch an anderer Stelle im Internet zu Tode diskutiert.

+0

Wäre es "sicherer" und "flexibler", einfach überall NSMutableString zu verwenden? Sie sagen, es gibt eine "Speicherkosten" und eine "Geschwindigkeitskosten" ... aber ... wie viel? 20 zusätzliche Bytes aus meinem Pool von Millionen? Oder verlangsame ich meine App um 0,01 Sekunden? (Die Vorteile von "sich nie um Mutables kümmern" scheint es wert.) Oder ist es? – Donna

+1

Wenn Sie gleichzeitige Programmierung verwenden (mehrere Threads usw.), ist es sehr angenehm zu wissen, dass sich der Inhalt Ihres Strings nicht mitten in der Verwendung ändert. Wenn Sie sich darüber Gedanken machen müssten, würden Sie wahrscheinlich eine Kopie der Zeichenfolge erstellen, bevor Sie etwas anderes tun, so dass niemand es ändern wird. Unveränderlichkeit macht es so, dass Sie die Zeichenkette nicht kopieren müssen. Dies wird für größere Strukturen wie NSArray und NSDictionary noch wichtiger. Wenn Sie nur einen Thread haben (wenn Sie nicht wissen, was das bedeutet, Sie haben nur einen), dann wäre die Verwendung von Mutables überall wahrscheinlich in Ordnung. –

+0

Auch wenn Sie nicht mehr als einen Thread verwenden, ist es schön zu wissen, ob sich ein Objekt unter Ihnen ändern kann. Im Allgemeinen finde ich es einfacher, die unveränderlichen Datenstrukturen die meiste Zeit zu verwenden. Wenn ich ein NSArray erstelle, es jemandem gebe und es dann weiter benutze, ist es hilfreich zu wissen, ob jemand es hinter meinem Rücken verändert hat. Kurz gesagt, die Verwendung von mutable überall ist einfacher zu schreiben, aber viel schwieriger zu debuggen. – rpetrich

11

Wenn ich eine Variable deklarieren:

NSString * var; 
// Here some code giving a new value to var 

Was unveränderlich ist, ist das Objekt von var spitz, nicht var selbst.

Das bedeutet, dass ich nichts von dem Objekt ändern kann, auf das var zeigt, aber ich kann ändern, auf welches Objekt verwiesen wird.

Keine der Operationen, die Sie erwähnen auf var erlaubt, aber man kann var mit einem anderen anderen String zuweisen:

NSString * anotherVar; 
// Here some code giving a new value to anotherVar 

var = anotherVar; // This is allowed (with a memory leak if GC is disabled) 

// The following is also allowed: -stringWithFormat: creates a new object 
var = [var stringWithFormat:@"%@ with more chars", var]; 
+0

Nur zu beachten, dass dieser Code * nicht * zu einem Speicherverlust führen sollte, wenn GC deaktiviert ist. Was Sie tun, ist eine einfache Zuweisung, die nicht mit -retain oder -copy durchgeführt wird. Daher kein Speicherverlust. Auch Ihr String-Format sollte @ "% @ mit mehr Zeichen" sein, da% s nur für C-Strings gilt, glaube ich. –

+0

Danke, ich habe das Format aktualisiert. Über das Speicherleck hängt es ab, wie der erste Wert von var erstellt wurde. – mouviciel

2

Eine unveränderliche Zeichenfolge (oder in der Tat, jedes unveränderliches Objekt) ist eine, die nicht sein kann nach der Initialisierung überhaupt geändert.

Hier ist der Vorteil von unveränderlichen Strings, in (Pseudo-) Pseudo-Code:

// if using mutable strings 
let a = "Hello World"; 
let b = a; 
a.replace("Hello", "Goodbye"); 

Nun, was einen Halt macht? "Hallo Welt"? "Auf Wiedersehen Welt"? Nun, was hält b?

Wenn Strings änderbar sind, kann es "Goodbye World" enthalten. Dies kann sein, was Sie wollen. Es könnte nicht sein.

Mit der Unveränderlichkeit wird sehr deutlich, dass b immer noch auf die ursprüngliche Zeichenkette zeigt, da die replace-Methode die tatsächliche Zeichenkette nicht hätte ändern können, sondern stattdessen einen Verweis auf eine neue Zeichenkette.

In diesem Beispiel wird möglicherweise kein großer Nutzen angezeigt. Wenn a und b jedoch in verschiedenen Teilen des Codes oder in verschiedenen Threads referenziert und verwendet werden, werden durch die Verwendung unveränderlicher Referenzen viele potenzielle Fehler beseitigt.

3

NSString kann nicht bearbeitet werden. Jedes Mal, wenn Sie dem NSString-Objekt einen Zeichenfolgenwert zuweisen, wird das alte Zeichenfolgenobjekt verwaist und das neue Zeichenfolgenobjekt neu erstellt. Das ist eine teure Operation, wenn Sie mit großem Zeichenfolgenpuffer arbeiten. Wenn Sie mit großem Zeichenfolgenpuffer arbeiten, verwenden Sie NSMutableString für optimale Leistung. Dies ist vergleichbar mit String vs StringBuilder in .net.

1

Standardmäßig ist NSString in der Zielsprache C unveränderlich. NSMutableString wird verwendet, um & eine veränderbare Zeichenfolge zu definieren. Nichts in einer unveränderlichen Zeichenkette kann geändert werden. Nicht die Länge, nicht die Charaktere, nichts.

Verwandte Themen