Avec cette classe simple, je reçois l' avertissement du compilateur
Tenter de modifier / accéder
x
à son propre setter / getter
et quand je l'utilise comme ça:
var p: point = Point()
p.x = 12
J'obtiens un EXC_BAD_ACCESS. Comment puis-je faire cela sans soutenir explicitement les ivars?
class Point {
var x: Int {
set {
x = newValue * 2 //Error
}
get {
return x / 2 //Error
}
}
// ...
}
set
vous voulez utiliserdidSet
. Les propriétés se comportent différemment dans Swift que dans Objective-C ou dans d'autres langages lorsque vous les implémentezset
. Voir la réponse ci-dessous de @jack et un exemple dedidSet
@cSquirrelRéponses:
Setters et Getters s'appliquent à
computed properties
; ces propriétés n'ont pas de stockage dans l'instance - la valeur du getter est censée être calculée à partir d'autres propriétés d'instance. Dans votre cas, il n'y a pasx
à attribuer.Explicitement: "Comment puis-je faire cela sans soutenir explicitement les ivars". Vous ne pouvez pas - vous aurez besoin de quelque chose pour sauvegarder la propriété calculée. Essaye ça:
Plus précisément, dans le Swift REPL:
la source
Les setters / getters dans Swift sont assez différents d'ObjC. La propriété devient une propriété calculée, ce qui signifie qu'elle n'a pas de variable de support telle
_x
qu'elle le ferait dans ObjC.Dans le code de solution ci-dessous, vous pouvez voir
xTimesTwo
que ne stocke rien, mais calcule simplement le résultat à partir dex
.Voir les documents officiels sur les propriétés calculées .
La fonctionnalité souhaitée peut également être Observateurs de propriétés .
Ce dont vous avez besoin c'est:
Vous pouvez modifier d'autres propriétés dans le setter / getters, ce à quoi elles sont destinées.
la source
didSet
ce qui vous permettra de modifier la valeur immédiatement après sa définition. Rien pour l'obtenir si ...x
revenir àoldValue
dansdidSet
. Ce changement de comportement est très déroutant en raison des propriétés d'Objective-C, merci!Vous pouvez personnaliser la valeur définie à l'aide de l'observateur de propriétés. Pour ce faire, utilisez «didSet» au lieu de «set».
Quant à getter ...
la source
x
avec une valeur par défaut dans ce modèle?var x: Int = 0 { didSet { ...
.Pour développer la réponse de GoZoner:
Votre vrai problème ici est que vous appelez récursivement votre getter.
Comme le commentaire de code le suggère ci-dessus, vous appelez à l'infini le getter de la propriété x, qui continuera à s'exécuter jusqu'à ce que vous obteniez un code EXC_BAD_ACCESS (vous pouvez voir le spinner dans le coin inférieur droit de l'environnement de jeu de votre Xcode).
Prenons l'exemple de la documentation Swift :
Remarquez comment la propriété calculée centrale ne se modifie jamais ou ne se renvoie jamais dans la déclaration de la variable.
la source
get
. Parce que cela en déclencherait un autreget
qui en déclencherait un autre. . . Ne l'imprimez même pas. Parce que l'impression nécessite également d'obtenir la valeur avant de pouvoir l'imprimer!Afin de remplacer
setter
etgetter
pour les variables rapides, utilisez le code ci-dessousNous devons conserver la valeur de variable dans une variable temporaire, car essayer d'accéder à la même variable dont le getter / setter est remplacé entraînera des boucles infinies.
On peut invoquer le setter simplement comme ça
Getter sera invoqué lors du tir sous la ligne de code donnée
la source
Vous définissez récursivement
x
avecx
. Comme si quelqu'un vous demandait quel âge avez-vous? Et vous répondez "J'ai deux fois mon âge". Ce qui n'a aucun sens.Vous devez dire que j'ai deux fois l'âge de John ou toute autre variable que vous-même.
les variables calculées dépendent toujours d'une autre variable.
La règle du pouce est jamais accéder à la propriété elle - même de l' intérieur du getter par exemple
get
. Parce que cela en déclencherait un autreget
qui en déclencherait un autre. . . Ne l'imprimez même pas. Parce que l'impression nécessite également d'obtenir la valeur avant de pouvoir l'imprimer!Comme cela donnerait l'avertissement suivant:
L'erreur ressemble à ceci:
Comme alternative, vous voudrez peut-être utiliser
didSet
. Avec,didSet
vous obtiendrez une prise sur la valeur qui a été définie avant et que vous venez de définir. Pour plus voir cette réponse .la source
Mise à jour: Swift 4
Dans la classe ci-dessous, setter et getter sont appliqués à la variable
sideLength
Création d'objet
Getter
Setter
la source
Essayez d'utiliser ceci:
C'est essentiellement la réponse de Jack Wu, mais la différence est que dans la réponse de Jack Wu, sa variable x est
var x: Int
, dans la mienne, ma variable x est comme ceci:,var x: Int!
donc tout ce que j'ai fait a été d'en faire un type optionnel.la source
Mise à jour pour Swift 5.1
Depuis Swift 5.1, vous pouvez désormais obtenir votre variable sans utiliser le mot clé get . Par exemple:
la source
Les setters et les getters dans Swift s'appliquent aux propriétés / variables calculées. Ces propriétés / variables ne sont pas réellement stockées en mémoire, mais plutôt calculées en fonction de la valeur des propriétés / variables stockées.
Voir la documentation Swift d'Apple sur le sujet: Déclarations de variables Swift .
la source
Voici une réponse théorique. Cela peut être trouvé ici
la source