Con esta clase simple obtengo la advertencia del compilador
Intentando modificar / acceder
x
dentro de su propio setter / getter
y cuando lo uso así:
var p: point = Point()
p.x = 12
Me sale un EXC_BAD_ACCESS. ¿Cómo puedo hacer esto sin respaldo explícito de ivars?
class Point {
var x: Int {
set {
x = newValue * 2 //Error
}
get {
return x / 2 //Error
}
}
// ...
}
set
que quieres usardidSet
. Las propiedades se comportan de manera diferente en Swift que Objective-C u otros lenguajes cuando se implementaset
. Vea la respuesta a continuación de @jack y un ejemplo dedidSet
@cSquirrelRespuestas:
Setters y Getters se aplican a
computed properties
; tales propiedades no tienen almacenamiento en la instancia; el valor del captador debe calcularse a partir de otras propiedades de la instancia. En su caso, no hayx
que asignarlo.Explícitamente: "¿Cómo puedo hacer esto sin respaldar explícitamente los ivars"? No puede: necesitará algo para hacer una copia de seguridad de la propiedad calculada. Prueba esto:
Específicamente, en Swift REPL:
fuente
Los setters / getters en Swift son bastante diferentes a ObjC. La propiedad se convierte en una propiedad calculada, lo que significa que no tiene una variable de respaldo
_x
como la que tendría en ObjC.En el código de solución a continuación, puede ver
xTimesTwo
que no almacena nada, sino que simplemente calcula el resultadox
.Ver documentos oficiales sobre propiedades calculadas .
La funcionalidad que desea también podría ser Observadores de propiedades .
Lo que necesitas es:
Puede modificar otras propiedades dentro del setter / getters, que es para lo que están destinadas.
fuente
didSet
que le permitirá cambiar el valor inmediatamente después de configurarlo. Nada para el get aunque ...x
volver a establecerlooldValue
endidSet
. Este cambio de comportamiento es muy confuso debido a las propiedades de Objective-C, ¡gracias!Puede personalizar el valor establecido utilizando el observador de propiedades. Para hacer esto, use 'didSet' en lugar de 'set'.
En cuanto a getter ...
fuente
x
con un valor predeterminado en este patrón?var x: Int = 0 { didSet { ...
.Para elaborar sobre la respuesta de GoZoner:
Su problema real aquí es que está llamando recursivamente a su captador.
Como el comentario del código sugiere anteriormente, está llamando infinitamente al captador de la propiedad x, que continuará ejecutándose hasta que obtenga un código EXC_BAD_ACCESS (puede ver el control giratorio en la esquina inferior derecha del entorno del patio de su Xcode).
Considere el ejemplo de la documentación de Swift :
Observe cómo la propiedad calculada del centro nunca se modifica o devuelve en la declaración de la variable.
fuente
get
. Porque eso desencadenaría otroget
que desencadenaría otro. . . Ni siquiera lo imprimas. ¡Porque la impresión también requiere 'obtener' el valor antes de poder imprimirlo!Para anular
setter
ygetter
para las variables rápidas, use el siguiente código dadoNecesitamos mantener el valor de variable en una variable temporal, ya que tratar de acceder a la misma variable cuyo anulador / establecedor se anulará dará como resultado bucles infinitos.
Podemos invocar al setter simplemente así
Getter será invocado al disparar debajo de la línea de código dada
fuente
Estás definiendo recursivamente
x
conx
. ¿Como si alguien te preguntara cuántos años tienes? Y respondes "Tengo el doble de mi edad". Lo cual no tiene sentido.Debe decir que tengo el doble de la edad de John o cualquier otra variable que no sea usted.
Las variables calculadas siempre dependen de otra variable.
La regla del pulgar es que nunca acceder a la propiedad en sí desde dentro del captador es decir
get
. Porque eso desencadenaría otroget
que desencadenaría otro. . . Ni siquiera lo imprimas. ¡Porque la impresión también requiere 'obtener' el valor antes de poder imprimirlo!Como eso daría la siguiente advertencia:
El error se ve vago como este:
Como alternativa, es posible que desee utilizar
didSet
. Con estodidSet
, mantendrá el valor que se estableció anteriormente y que acaba de establecerse en. Para más ver esta respuesta .fuente
Actualización: Swift 4
En el siguiente setter de clase y getter se aplica a la variable
sideLength
Creando objeto
Adquiridor
Setter
fuente
Intenta usar esto:
Esta es básicamente la respuesta de Jack Wu, pero la diferencia es que en la respuesta de Jack Wu su variable x es
var x: Int
, en la mía, mi variable x es así:var x: Int!
así que todo lo que hice fue convertirla en un tipo opcional.fuente
Actualización para Swift 5.1
A partir de Swift 5.1 ahora puede obtener su variable sin usar la palabra clave get . Por ejemplo:
fuente
Los establecedores y captadores en Swift se aplican a las propiedades / variables calculadas. Estas propiedades / variables no se almacenan realmente en la memoria, sino que se calculan en función del valor de las propiedades / variables almacenadas.
Consulte la documentación de Swift de Apple sobre el tema: Declaraciones de variables de Swift .
fuente
Aquí hay una respuesta teórica. Eso se puede encontrar aquí
fuente