4 Stimmen

Sind veränderbare Klassen "schwerer"?

Aufgrund einer intuitiven (vielleicht falschen) Vorstellung von Leistung erhalte ich immer eine copy einer veränderbaren Instanz, bevor ich sie speichere. Wenn also eine Eigenschaft eine NSArray Ich nehme das veränderbare Array, mit dem ich arbeite, und speichere es als self.array = mutableArray.copy (obwohl die Eigenschaft angegeben ist als strong o retain ).

Das kommt mir plötzlich dumm vor, aber ist es das? Führen veränderliche Instanzen, die genau dieselbe Aufgabe erfüllen, dasselbe durch?

Anmerkung: Die veränderbare Instanz fällt aus dem Anwendungsbereich und wird (dank ARC) direkt danach freigegeben, so dass man sich keine Sorgen machen muss, dass sie verändert wird, sobald sie der Eigenschaft zugewiesen ist.

3voto

Nick Lockwood Punkte 40439

Teilweise hier beantwortet: NSArray Größe und Veränderbarkeit

NSMutableArray ist nicht merklich langsamer oder größer (speichertechnisch) als ein NSArray. Es ist im Grunde nur ein NSArray, das sich selbst neu zuordnet, wenn es voll ist, als größeres Array, und hält das tun, wie Sie Elemente zu ihm hinzufügen.

Der Grund für das Kopieren von veränderlichen Arrays als unveränderliche Arrays, wenn Sie sie Werten in Ihrer Klasse zuweisen, ist, dass Sie garantieren können, dass sich ihre Werte nicht ändern. Wenn Sie ein veränderbares Array in Ihrer Klasse speichern, kann anderer Code seine Werte außerhalb Ihrer Klasse ändern, ohne eine Ihrer Methoden aufzurufen. Das macht Sie anfällig für Abstürze aufgrund von internen Instabilitätsfehlern innerhalb Ihrer Klassen.

Nehmen wir zum Beispiel an, dass Sie beim Setzen des Arrays die Länge des Arrays als int-Eigenschaft in Ihrer Klasse zwischengespeichert haben. Das wäre in Ordnung, wenn das Array unveränderlich wäre, aber wenn es veränderbar wäre, könnte jemand anderes das Array ändern, und Ihr zwischengespeicherter Wert wäre jetzt falsch, aber Sie haben keine Möglichkeit, das zu wissen.

Es ist jedoch nicht notwendig, das Kopieren manuell durchzuführen. Wenn Sie Ihre Array-Eigenschaften deklarieren als:

@property (nonatomic, copy) NSArray *foo;

Wenn Sie dann object.foo ein Array zuweisen, wird es automatisch kopiert. Sie brauchen es nicht noch einmal selbst zu kopieren. Es ist am besten, eine Eigenschaft vom Typ copy anstelle von strong/retain für jeden Typ zu verwenden, der eine veränderbare Variante hat, wie zum Beispiel so:

@property (nonatomic, copy) NSArray *foo;
@property (nonatomic, copy) NSString *foo;
@property (nonatomic, copy) NSDictionary *foo;
@property (nonatomic, copy) NSData *foo;
etc...

Seien Sie jedoch vorsichtig, es nicht für veränderbare Eigenschaften zu verwenden, da sonst eine unveränderbare Kopie in einer Eigenschaft gespeichert wird, die denkt, dass sie veränderbar ist und einen Absturz verursacht, wenn Sie versuchen, sie zu verändern. Die synthetische Kopie Eigenschaft ist nicht intelligent genug, um mutableCopy automatisch zu verwenden.

@property (nonatomic, copy) NSMutableArray *foo; //don't do this

3voto

jscs Punkte 63009

NSArray y NSMutableArray sind beide (soweit ich weiß) auf der Grundlage von CFArray die einfach ein Flag hat, das angibt, ob sie veränderbar ist. CFArray Funktionen, die ein veränderbares Array erfordern, haben gleich zu Beginn eine Assertion, die dieses Flag überprüft:

void CFArraySetValueAtIndex(CFMutableArrayRef array, CFIndex idx, const void *value) {
    // snip...
    CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);

Veränderlich und unveränderlich CFArray s sind identisch, außer dass sie diese Behauptung bestehen oder nicht bestehen, und sollten daher NSArray s und NSMutableArray s sein, sei es in Bezug auf die Leistung oder in anderer Hinsicht.

2voto

Matt Wilding Punkte 19980

Für Klarheit, die Sie fragen, wenn gegeben ein NSArray und ein NSMutableArray beide unterzogen, um eine Batterie von nicht-Mutation-Test-Methoden, führt die NSArray spürbar schneller? Ich spezifiziere nicht-mutierend, weil es so aussieht, als ob Sie ein veränderbares Array in ein unveränderbares Array kopieren, in dem Glauben, dass das unveränderbare Array seine nicht-mutierenden Methoden schneller ausführen wird als das veränderbare Array. Wie auch immer, die Antwort ist nein. (Aber nehmen Sie nicht mein Wort dafür; Profil).

Selbst wenn NSMutableArray einige nicht-mutierende Methoden überschreibt (was wir nicht wissen können, eine oder andere Weise), würden Sie nicht brauchen, um darüber zu kümmern. Das Hinzufügen von ein paar CPU-Zyklen ist trivial im Vergleich zu der gesamten Rechenkomplexität der Operation. Solange NSMutableArray es nicht schafft, eine O(n) Lookup-Operation in eine O(n 2 ), werden Sie in 99 % der Fälle keine Probleme haben. (Diese Komplexitäten sind nur fiktive Beispiele).

Es gibt zwar durchaus triftige Gründe, warum man ein veränderbares Array in ein unveränderbares Array kopieren möchte (wie von @NickLockwood hervorgehoben), aber die Leistung sollte nicht einer davon sein. Eine verfrühte Optimierung ist schließlich sehr schlecht.

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