Mit dieser einfachen Klasse erhalte ich die Compiler- Warnung
Versuch,
x
innerhalb seines eigenen Setters / Getters zu ändern / darauf zuzugreifen
und wenn ich es so benutze:
var p: point = Point()
p.x = 12
Ich bekomme eine EXC_BAD_ACCESS. Wie kann ich dies tun, ohne Ivars explizit zu unterstützen?
class Point {
var x: Int {
set {
x = newValue * 2 //Error
}
get {
return x / 2 //Error
}
}
// ...
}
set
Sie verwenden möchtendidSet
. Eigenschaften verhalten sich bei der Implementierung in Swift anders als in Objective-C oder anderen Sprachenset
. Siehe die Antwort unten von @jack und ein BeispieldidSet
von @cSquirrelAntworten:
Setter und Getter gelten für
computed properties
; Solche Eigenschaften haben keinen Speicher in der Instanz - der Wert vom Getter soll aus anderen Instanzeigenschaften berechnet werden. In Ihrem Fall ist keinex
zuzuweisen.Explizit: "Wie kann ich dies tun, ohne Ivars explizit zu unterstützen?" Sie können nicht - Sie benötigen etwas, um die berechnete Eigenschaft zu sichern. Versuche dies:
Insbesondere in der Swift REPL:
quelle
Setter / Getter in Swift sind ganz anders als ObjC. Die Eigenschaft wird zu einer berechneten Eigenschaft das heißt , es ist nicht einen Träger Variable wie
_x
wie es wäre , in ObjC.In der Code - Lösung unten können Sie sehen , das
xTimesTwo
ist nicht alles speichern, sondern einfach berechnet das Ergebnis ausx
.Siehe Offizielle Dokumente zu berechneten Eigenschaften .
Die gewünschte Funktionalität kann auch Property Observers sein .
Was Sie brauchen ist:
Sie können andere Eigenschaften innerhalb des Setters / Getters ändern, wofür sie bestimmt sind.
quelle
didSet
, um den Wert unmittelbar nach dem Festlegen zu ändern. Nichts für das Get obwohl ...x
um wiederoldValue
in diedidSet
. Diese Verhaltensänderung ist aufgrund der Objective-C-Eigenschaften sehr verwirrend, danke!Sie können den eingestellten Wert mit dem Eigenschaftsbeobachter anpassen. Verwenden Sie dazu 'didSet' anstelle von 'set'.
Wie für Getter ...
quelle
x
mit einem Standardwert in diesem Muster initialisieren ?var x: Int = 0 { didSet { ...
.Um die Antwort von GoZoner zu erläutern:
Ihr eigentliches Problem hierbei ist, dass Sie Ihren Getter rekursiv anrufen.
Wie der obige Codekommentar andeutet, rufen Sie den Getter der x-Eigenschaft unendlich auf, der so lange ausgeführt wird, bis Sie einen EXC_BAD_ACCESS-Code erhalten (Sie können den Spinner in der unteren rechten Ecke der Spielplatzumgebung Ihres Xcodes sehen).
Betrachten Sie das Beispiel aus der Swift-Dokumentation :
Beachten Sie, dass die berechnete Eigenschaft center in der Deklaration der Variablen niemals geändert oder zurückgegeben wird.
quelle
get
. Denn das würde einen anderenget
auslösen, der einen anderen auslösen würde. . . Drucken Sie es nicht einmal aus. Weil beim Drucken auch der Wert "abgerufen" werden muss, bevor er gedruckt werden kann!Verwenden Sie zum Überschreiben
setter
undgetter
für schnelle Variablen den unten angegebenen CodeWir müssen den Wert der Variablen in einer temporären Variablen behalten, da der Versuch, auf dieselbe Variable zuzugreifen, deren Getter / Setter überschrieben wird, zu Endlosschleifen führt.
Wir können den Setter einfach so aufrufen
Getter wird beim Abfeuern unterhalb der angegebenen Codezeile aufgerufen
quelle
Sie definieren rekursiv
x
mitx
. Als ob dich jemand fragt, wie alt du bist? Und du antwortest "Ich bin doppelt so alt wie ich". Welches ist bedeutungslos.Sie müssen sagen, ich bin doppelt so alt wie John oder eine andere Variable als Sie.
Berechnete Variablen sind immer von einer anderen Variablen abhängig.
Die Faustregel lautet, niemals von innen auf die Eigenschaft selbst zuzugreifen der Getter dh
get
. Denn das würde einen anderenget
auslösen, der einen anderen auslösen würde. . . Drucken Sie es nicht einmal aus. Weil beim Drucken auch der Wert "abgerufen" werden muss, bevor er gedruckt werden kann!Da würde die folgende Warnung geben:
Der Fehler sieht vage aus:
Alternativ können Sie auch verwenden
didSet
. Mit erhaltendidSet
Sie einen Halt für den Wert, der zuvor eingestellt wurde und auf den gerade eingestellt wurde. Weitere Informationen finden Sie in dieser Antwort .quelle
Update: Swift 4
In der folgenden Klasse werden Setter und Getter auf Variablen angewendet
sideLength
Objekt erstellen
Getter
Setter
quelle
Versuchen Sie Folgendes:
Dies ist im Grunde die Antwort von Jack Wu, aber der Unterschied besteht darin, dass in Jack Wus Antwort seine x-Variable lautet
var x: Int
, in meiner ist meine x-Variable wie folgt:var x: Int!
Also habe ich sie nur zu einem optionalen Typ gemacht.quelle
Update für Swift 5.1
Ab Swift 5.1 können Sie Ihre Variable jetzt ohne das Schlüsselwort get abrufen. Beispielsweise:
quelle
Setter und Getter in Swift gelten für berechnete Eigenschaften / Variablen. Diese Eigenschaften / Variablen werden nicht tatsächlich im Speicher gespeichert, sondern basierend auf dem Wert der gespeicherten Eigenschaften / Variablen berechnet.
Weitere Informationen finden Sie in der Swift-Dokumentation von Apple zum Thema: Swift-Variablendeklarationen .
quelle
Hier ist eine theoretische Antwort. Das kann gefunden werden hier
quelle