¿Qué son 'obtener' y 'configurar' en Swift?


101

Estoy aprendiendo Swift y estoy leyendo The Swift Programming Language de Apple, no tengo experiencia en Objective C (solo PHP, JS y otros, pero no Obj C)

En la página 24-25 veo este código:

//...Class definition stuff...

var perimeter: Double {
    get {
        return 3.0 * sideLength
    }
    set {
        sideLength = newValue / 3.0
    }
}

//...Class continues...

Esta parte NO está especificada en el libro y no puedo obtener para qué sirven.

¿Alguien puede explicarme qué son obtener y configurar ?


2
¿Leíste la página 21 sobre getter / setter? Además, las primeras 30 páginas son un recorrido por Swift y no la documentación completa.
vol7ron

Si ha hecho C ++, puede co-relacionar estas cosas con las funciones de miembro getter y setter de la clase
CodingOnSteroid

Respuestas:


38

En realidad, eso se explica justo antes del código:

Además de las propiedades simples que se almacenan, las propiedades pueden tener un getter y un setter.

class EquilateralTriangle: NamedShape {
    ...

Cuando alguna otra clase quiere obtener esa variable de perímetro, hacen esto:

let someVar = myTriangle.perimeter

... Que llama a esto:

get{
    return 3.0 * self.sideLength
}

Y, por lo tanto, es esencialmente como si el controlador de llamada hiciera esto:

let someVar = 3.0 * myTriangle.sideLength

Cuando establece la variable de otro objeto, se ve así:

myTriangle.perimeter = 100

Que invoca el código en el set{}bloque:

set {
    sideLength = newValue / 3.0
}

Y es como si la clase que está configurando la variable hubiera hecho esto:

myTriangle.sideLength = 100/3.0

Es realmente solo por conveniencia : puede llamar a esto desde otro código sin tener que dividir o multiplicar por 3 todo el tiempo, porque eso se hace justo antes de establecer la variable y justo antes de obtener la variable.

En Swift, podemos tener propiedades que se calculan cuando se obtienen y pueden hacer algo cuando se establecen. También podríamos hacer esto en Objective-C:

// .h
@property (nonatomic) double perimeter;

//.m

- (double)perimeter
{
    return self.sideLength * 3.0;
}
- (void)setPerimeter:(double)perimeter
{
    self.perimeter = perimeter; // In Swift, this is done automatically.
    self.sideLength = perimeter / 3.0;
}

108

La obtención y configuración de variables dentro de las clases se refiere a recuperar ("obtener") o alterar ("configurar") su contenido.

Considere una variable membersde una clase family. Naturalmente, esta variable debería ser un número entero, ya que una familia nunca puede estar formada por personas de dos puntos.

Entonces probablemente seguiría adelante definiendo la membersvariable de esta manera:

class family {
   var members:Int
}

Sin embargo, esto le dará a las personas que usan esta clase la posibilidad de establecer el número de miembros de la familia en algo como 0 o 1. Y dado que no existe una familia de 1 o 0, esto es bastante desafortunado.

Aquí es donde entran los captadores y definidores. De esta manera, puede decidir por sí mismo cómo se pueden alterar las variables y qué valores pueden recibir, así como decidir qué contenido devuelven.

Volviendo a nuestra clase familiar, asegurémonos de que nadie pueda establecer el membersvalor en menos de 2:

class family {
  var _members:Int = 2
  var members:Int {
   get {
     return _members
   }
   set (newVal) {
     if newVal >= 2 {
       _members = newVal
     } else {
       println('error: cannot have family with less than 2 members')
     }
   }
  }
}

Ahora podemos acceder a la membersvariable como antes, escribiendo instanceOfFamily.members, y gracias a la función de organismo, también podemos configurarlo de valor que antes, por escribir, por ejemplo: instanceOfFamily.members = 3. Sin embargo, lo que ha cambiado es el hecho de que ya no podemos establecer esta variable en un valor menor que 2.

Tenga en cuenta la introducción de la _membersvariable, que es la variable real para almacenar el valor que establecemos a través de la membersfunción setter. El original membersahora se ha convertido en una propiedad calculada, lo que significa que solo actúa como una interfaz para tratar con nuestra variable real.


members==> count, numberOfMembers; var members : Set<Person>??
GoZoner

1
set (newVal) { ... }, newVal está implícito, por set { _members = newVal }lo que también es correcto.
AndreasHassing

4
Tenga en cuenta que las variables como _membersdeben ser privadas; de lo contrario, el comando instanceOfFamily._members=1se establecería instanceOfFamily.membersen un valor inferior a 2
Daniel

Parece que el parámetro predeterminado se nombra newValueen Swift 4 - docs.swift.org/swift-book/LanguageGuide/Properties.html#ID260
Nolan Amy

18

Una pregunta sencilla debe ir seguida de una respuesta breve, sencilla y clara.

  • Cuando obtenemos un valor de la propiedad, dispara su get{}parte.

  • Cuando establecemos un valor para la propiedad, dispara su set{}parte.

PD. Al establecer un valor para la propiedad, SWIFT crea automáticamente una constante denominada "newValue" = un valor que estamos configurando. Después de que un "newValue" constante se vuelve accesible en la set{}parte de la propiedad .

Ejemplo:

var A:Int = 0
var B:Int = 0

var C:Int {
get {return 1}
set {print("Recived new value", newValue, " and stored into 'B' ")
     B = newValue
     }
}

//When we are getting a value of C it fires get{} part of C property
A = C 
A            //Now A = 1

//When we are setting a value to C it fires set{} part of C property
C = 2
B            //Now B = 2

1
¿Es obligatorio asignar un valor predeterminado para que los miembros accedan desde fuera de la clase? Tuve este problema como solucionado cuando le asigno un valor predeterminado para la clase UserBean: NSObject {var user_id: String? = nil} accediendo a él de la siguiente manera permite al usuario: UserBean = UserBean () user.user_id = "23232332"
Amr Angry

1

Debería mirar Propiedades calculadas

En su ejemplo de código, perimeteres una propiedad que no está respaldada por una variable de clase, sino que su valor se calcula usando el getmétodo y se almacena a través del setmétodo, generalmente denominado getter y setter .

Cuando usa esa propiedad de esta manera:

var cp = myClass.perimeter

está invocando el código contenido en el getbloque de código, y cuando lo usa así:

myClass.perimeter = 5.0

está invocando el código contenido en el setbloque de código, donde newValuese completa automáticamente con el valor proporcionado a la derecha del operador de asignación.

Las propiedades calculadas se pueden leer y escribir si se especifican tanto un getter como un setter, o solo lectura si solo se especifica el getter.


0

variable declara y llama así en una clase

class X {
    var x: Int = 3

}
var y = X()
print("value of x is: ", y.x)

//value of x is:  3

ahora desea programar para que el valor predeterminado de x sea mayor o igual a 3. Ahora tome el caso hipotético si x es menor que 3, su programa fallará. por lo tanto, desea que la gente coloque 3 o más de 3. Swift lo hizo fácil para usted y es importante comprender esta forma avanzada de fechar el valor de la variable porque la usarán ampliamente en el desarrollo de iOS. Ahora veamos cómo se usarán aquí get y set.

class X {
    var _x: Int = 3
    var x: Int {
        get {
            return _x
        }
        set(newVal) {  //set always take 1 argument
            if newVal >= 3 {
             _x = newVal //updating _x with the input value by the user
            print("new value is: ", _x)
            }
            else {
                print("error must be greater than 3")
            }
        }
    }
}
let y = X()
y.x = 1
print(y.x) //error must be greater than 3
y.x = 8 // //new value is: 8

Si aún tiene dudas, recuerde, el uso de get y set es para actualizar cualquier variable de la forma que queremos que se actualice. get and set le dará un mejor control para gobernar su lógica. Herramienta potente, por tanto, no fácilmente comprensible.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.