20 Stimmen

Was ist die Logik hinter einer veränderbaren und unveränderbaren Versionen von Klassen wie NSArray, NSDictionary usw. in Objective C?

Warum haben gängige Auflistungsklassen in Objective C wie NSString, NSArray, NSDictionary usw. sowohl eine veränderbare als auch eine unveränderbare Version? Welche Logik steckt dahinter, sie getrennt zu definieren? Leistung, Speicherverwaltung oder etwas anderes?

14voto

bbum Punkte 161596

Die unveränderlichen Versionen der Klassen existieren, weil ein unveränderliches Objekt an und für sich ein eindeutige Kennung für einen bestimmten Staat . D.h. wenn Sie eine NSArray von 100 NSString Instanzen, die NSArray Instanz kann für jede dieser Zeichenketten als idempotent behandelt werden.

Außerdem bedeutet die Unveränderlichkeit, dass eine Änderung nicht mehr möglich ist, nachdem der Zustand verkauft worden ist. Zum Beispiel, NSView 's subviews Methode gibt ein unveränderliches Array zurück und stellt damit sicher, dass der Aufrufer keine Spielchen mit dem Inhalt treiben kann (und auch nicht erwartet, dass er das kann). Intern, NSView könnte wählen, um das [wahrscheinliche] NSMutableArray zurückzugeben, das die Unteransichten enthält (da es intern veränderbar ist) und den Typecast zu NSArray bedeutet, dass der Aufrufer den Inhalt nicht ohne einen bösen Cast oder eine schlechte Compilerwarnung manipulieren kann. (Dies kann, muss aber nicht die tatsächliche Implementierung sein, aber dieses Muster wird anderswo verwendet).

Unveränderlichkeit bedeutet auch, dass Enumeration und/oder Traversal ohne das Risiko einer Zustandsänderung in der Mitte durchgeführt werden können. In ähnlicher Weise sind viele unveränderliche Klassen auch ausdrücklich thread-sicher; eine beliebige Anzahl von Threads kann den unveränderlichen Zustand gleichzeitig lesen, oft ohne dass eine Sperre erforderlich ist.

12voto

Im Allgemeinen für eine API, eine unveränderliche Klasse wird Thread sicher sein, so dass Sie es direkt in einem Hintergrund-Thread lesen können, ohne zu befürchten, dass der Inhalt ändern wird...

Das ist eher für Dinge wie eine Sammlung von Bedeutung, deren Inhalt sich verschieben kann und die Sie vielleicht gerade aufzählen wollen.

10voto

justin Punkte 103032

Warum haben gängige Auflistungsklassen in Objective C wie NSString, NSArray, NSDictionary usw. sowohl eine veränderbare als auch eine unveränderbare Version?

das konzept wird in verwandten sprachen verwendet. der bemerkenswerte unterschied besteht darin, dass die objc-typen als veränderbare varianten bezeichnet werden. ähnliche sprachen erreichen dies typischerweise durch die anwendung eines schlüsselworts, wie const Natürlich verwenden auch andere verwandte Sprachen Typen, die ausdrücklich veränderbar oder unveränderbar sind.

Welche Logik steckt dahinter, sie getrennt zu definieren?

objc messaging unterscheidet nicht zwischen const und non-const, und die Sprache bietet keine eingebaute Unterstützung, um sicherzustellen, dass sich der Zustand eines Objekts nicht ändert (obwohl es wirklich keine schwierige Ergänzung wäre, wenn man wirklich geneigt wäre, einen Compiler zu erweitern). also ist auch hier ein bisschen Geschichte im Spiel.

Daher ist es für die Klasse üblich, Unveränderlichkeit und Veränderlichkeit zu definieren und Varianten zu liefern, die die Veränderlichkeit unterscheiden.

Mehrere Abstraktionen führen auch Typsicherheit und Absicht ein.

Leistung

Ja, es gibt mehrere Optimierungen, die ein invariantes Objekt vornehmen kann.

einige Fälle umfassen:

  • es könnte Werte zwischenspeichern und sie nie mehr als einmal berechnen.
  • es könnte exakte, nicht veränderbare Zuweisungen für seine Daten verwenden.
  • Für die Verwendung im Multithreading ist oft kein spezieller Code erforderlich - viele unveränderliche Typen ändern sich nur während der Erstellung bzw. Zerstörung.
  • Diese Typen verwenden häufig Klassencluster. Wenn ein Klassencluster implementiert wird, können spezialisierte Implementierungen erhebliche Unterschiede in Bezug auf Speicher, Implementierung usw. aufweisen. So könnte sich eine unveränderliche Zeichenfolge mit genau einem Zeichen von einer veränderlichen Variante unterscheiden.

Speicherverwaltung

einige Fälle umfassen:

  • unveränderliche Typen ihren unveränderlichen Inhalt gemeinsam nutzen können.
  • Sie können auch die Zuteilungen reduzieren. Zum Beispiel kann eine Implementierung von copyWithZone: o initWithType: könnte die beibehaltene Quelle zurückgeben, anstatt einer tiefen oder flachen physischen Kopie.

oder etwas anderes?

es macht es einfacher, klare schnittstellen zu schreiben. man kann einige dinge garantieren und (versuchen) einzuschränken. wenn alles veränderbar wäre, gäbe es viel mehr fehler und sonderfälle. tatsächlich könnte die unterscheidung die art und Weise, wie wir an das schreiben von objc-bibliotheken herangehen, völlig verändern:

[[textField stringValue] appendString:@" Hz"];
[textField stateDidChange];

Es ist also schön, dass man Objekte weitergeben kann, ohne sich Sorgen machen zu müssen, dass der Client hinter dem eigenen Rücken Änderungen vornimmt, während man gleichzeitig vermeidet, überall hin zu kopieren.

8voto

Dave DeLong Punkte 240835

Wenn man weiß, dass eine Datenstruktur unveränderlich ist, kann man viele Optimierungen vornehmen, die diese Tatsache berücksichtigen. Wenn zum Beispiel ein Array unveränderlich ist, kann man den ganzen Code weglassen, der das Array "wachsen" lassen würde, wenn man versucht, ein Objekt hinzuzufügen, und man kann das unveränderliche Array einfach als Wrapper um ein id[] .

-1voto

Abgesehen von den oben genannten Antworten besteht ein Unterschied: Unveränderliche Objekte sind im Allgemeinen thread-sicher. Veränderbare Objekte sind hingegen nicht thread-sicher.

danke

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X