Ich lese in Kakao und Ziel C: Auf und ab , dass -copy
immer zurückkehrt Ein unveränderliches Objekt und -mutableCopy
geben immer ein veränderbares Objekt zurück:
Es ist wichtig zu wissen, dass das Aufrufen von
-copy
auf einem veränderbaren Objekt ein unveränderliches Objekt zurückgibt Ausführung. Wenn Sie ein änderbares Objekt kopieren und die Änderbarkeit in der neuen Version beibehalten möchten, Sie müssen-mutableCopy
für das Original aufrufen. Dies ist jedoch nützlich, wenn Sie möchten Um ein veränderbares Objekt "einzufrieren", können Sie einfach-copy
aufrufen.
Ich habe also so etwas:
%Vor%Nach dieser vorherigen Antwort :
Sie können sich nicht darauf verlassen, dass das Ergebnis der Kopie veränderbar ist! Kopieren eines
NSMutableArray
kann gib einNSMutableArray
zurück, da das die ursprüngliche Klasse ist, aber beliebig kopierenNSArray
Instanz würde nicht.
Dies scheint etwas isoliert zu NSURLRequest
zu sein, da NSArray
wie vorgesehen funktioniert:
Also ...
-copy
ein unveränderliches Objekt zurück (wie erwartet) und wann gibt es ein veränderbares Objekt zurück? Ich denke, Sie haben eine große Kluft zwischen Dokumentation und Realität aufgedeckt.
Die NSCopying-Protokolldokumentation behauptet:
Die zurückgegebene Kopie ist unveränderlich, wenn die Betrachtung "unveränderlich vs. veränderbar" für das empfangende Objekt gilt; Andernfalls wird die genaue Art der Kopie durch die Klasse bestimmt.
Aber das ist in einigen Fällen eindeutig falsch, wie Sie in Ihren Beispielen gezeigt haben (und ich habe ihnen über diese Dokumentationsseite Feedback dazu geschickt).
Aber (# 2) meiner Meinung nach spielt es eigentlich keine Rolle, und Sie sollten sich nicht darum kümmern.
Der Punkt von -copy
ist, dass es ein Objekt zurückgibt, das verwendet, mit der Garantie, dass es sich unabhängig vom Original verhält. Dies bedeutet, wenn Sie ein veränderbares Objekt haben, -copy
es, und ändern Sie das ursprüngliche Objekt, die Kopie wird nicht den Effekt sehen. (In manchen Fällen bedeutet dies, dass -copy
optimiert werden kann, um nichts zu tun, denn wenn das Objekt unveränderlich ist, kann es nicht von vornherein geändert werden. Ich kann mich deswegen irren. (Ich frage mich jetzt was die Implikationen für Dictionary Keys aus diesem Grund sind, aber das ist ein separates Thema ...))
Wie Sie gesehen haben, kann das neue Objekt in einigen Fällen eine veränderbare Klasse sein (auch wenn die Dokumentation es nicht sagt). Aber solange du dich nicht darauf verlässt, dass es veränderbar ist (warum würdest du?), Ist es egal.
Was sollten Sie tun? Behandle das Ergebnis von -copy
immer als unveränderlich , einfach so.
1) Wann gibt -copy ein unveränderliches Objekt zurück (wie erwartet) und wann gibt es ein veränderbares Objekt zurück?
Sie sollten es immer als die unveränderliche Variante behandeln. Die änderbare Schnittstelle des zurückgegebenen Typs sollte nicht verwendet werden. Abgesehen von Optimierungen sollte die Antwort keine Rolle spielen und sollte als Implementierungsdetail betrachtet werden, sofern nicht dokumentiert.
Der offensichtliche Fall: Objc-Klassencluster und Klassenentwürfe können aus einer Reihe von Gründen komplex sein. Die Rückgabe einer veränderbaren Kopie könnte einfach nur der Bequemlichkeit dienen.
2) Wie erreiche ich den beabsichtigten Effekt, eine "eingefrorene" Kopie eines veränderbaren Objekts zu erhalten, das nicht "eingefroren" werden kann?
mit dem Kopierkonstruktor der unveränderlichen Klasse ist ein guter Weg (ähnlich der Antwort von St3fan). wie copy
, es ist keine Garantie.
Der einzige Grund, warum ich mir vorstellen kann, warum Sie dieses Verhalten erzwingen möchten, ist die Leistung oder die Durchsetzung einer eingeschränkten Schnittstelle (es sei denn, es ist akademisch). Wenn Sie eine Performance oder eine eingeschränkte Schnittstelle wünschen, können Sie einfach eine Instanz des Typs kapseln, der bei der Erstellung kopiert wird, und nur die unveränderliche Schnittstelle verfügbar machen. dann implementieren Sie kopieren über behalten (wenn das Ihre Absicht ist).
Alternativ können Sie Ihre eigene Unterklasse schreiben und Ihre eigene Variante der Kopie implementieren.
letzter Ausweg: Viele der veränderbaren / unveränderlichen Kakao-Klassen sind reine Schnittstellen - Sie könnten Ihre eigene Unterklasse schreiben, wenn Sie ein bestimmtes Verhalten sicherstellen müssen - aber das ist ziemlich ungewöhnlich.
vielleicht eine bessere Beschreibung, warum dies durchgesetzt werden sollte, wäre gut - die vorhandenen Implementierungen funktionieren gut für die überwiegende Mehrheit der Entwickler / Anwendungen.
Bedenken Sie, dass es keine copy
-Implementierung gibt - jede Klasse implementiert ihre eigene. Und wie wir alle wissen, ist die Implementierung der Objective-C-Laufzeit ein wenig "loosey goosey" in Punkten. Also ich denke, wir können sagen, dass meist copy
eine unveränderbare Version zurückgibt, aber einige Ausnahmen existieren.
(Übrigens, was macht das?
%Vor%?)
Der beste Weg, ein Objekt in ein veränderbares Objekt zu verwandeln, ist der veränderbare 'Konstruktor'. Wie zum Beispiel:
%Vor%Kopieren wird verwendet, um eine Kopie eines Objekts zu erstellen. Um es nicht zu verändern ist es möglich.
Tags und Links objective-c cocoa mutable nsmutableurlrequest