¿Cuándo debería acceder a las propiedades con auto en swift?

En un ejemplo simple como este, puedo omitir self para hacer referencia a backgroundLayer porque no es ambiguo en qué backgroundLayer se establece el backgroundColor.

class SpecialView: UIView { let backgroundLayer = CAShapeLayer() init() { backgroundLayer.backgroundColor = UIColor.greenColor().CGColor } } 

Pero, al igual que en Objective-C, podemos confundir las cosas al agregar variables locales (o constantes) nombradas de manera similar. Ahora el backgroundColor se está configurando en la capa sin forma:

 class SpecialView: UIView { let backgroundLayer = CAShapeLayer() init() { var backgroundLayer = CALayer() backgroundLayer.backgroundColor = UIColor.greenColor().CGColor } } 

(Esto se resuelve mediante el uso de self.backgroundLayer.backgroundColor)

En Objective-C siempre evité ivars para las propiedades y las propiedades siempre fueron prefijadas con self para mayor claridad. No tengo que preocuparme por los ivars de forma rápida, pero ¿hay otras consideraciones sobre cuándo debo usar mi yo a la ligera?

Las únicas ocasiones en que se requiere autoejecución son cuando se hace referencia a una propiedad dentro de un cierre y, como usted señaló, para diferenciarlo de una variable local con el mismo nombre.

Sin embargo, personalmente, prefiero escribir siempre “yo” porque:

  1. Esa es una señal instantánea y obvia de que la variable es una propiedad. Esto es importante porque al ser una propiedad significa que su estado puede variar más ampliamente y de diferentes maneras que una variable local. Además, cambiar una propiedad tiene implicaciones más grandes que cambiar una variable local.
  2. El código no necesita actualizarse si decide introducir un parámetro o variable con el mismo nombre que la propiedad
  3. El código se puede copiar fácilmente dentro y fuera de cierres que sí requieren

La mayoría de las veces podemos omitirnos self. cuando accedemos a las propiedades de la clase.

  1. Sin embargo, hay un momento en que DEBEMOS usarlo: cuando intentamos establecer self.property en un cierre:

     dispatch_async(dispatch_get_main_queue(), { // we cannot assign to properties of self self.view = nil // but can access properties someFunc(view) }) 
  2. una vez cuando DEBERÍAMOS usarlo: para que no se meta una variable local con propiedad de clase:

     class MyClass { var someVar: String = "class prop" func setProperty(someVar:String = "method attribute") -> () { print(self.someVar) // Output: class property print(someVar) // Output: method attribute } } 
  3. otros lugares donde podemos usar el self. antes de que la propiedad fuera solo expresiva sobre de donde viene la variable / constante.

Mirando la guía de estilo de Ray Wenderlich

Uso de uno mismo

Para mayor concisión, evite usar self ya que Swift no requiere que acceda a las propiedades de un objeto ni invoque sus métodos.

Utilice self solo cuando lo requiera el comstackdor (en los cierres de @escaping o en los inicializadores para eliminar la ambigüedad de las propiedades de los argumentos). En otras palabras, si se comstack sin uno, entonces omítalo.

La documentación de Swift hace la misma recomendación.

La propiedad propia

Cada instancia de un tipo tiene una propiedad implícita llamada self, que es exactamente equivalente a la instancia en sí misma. Utiliza la propiedad de self para referirse a la instancia actual dentro de sus propios métodos de instancia.

El método increment() en el ejemplo anterior podría haberse escrito así:

 func increment() { self.count += 1 } 

En la práctica, no necesita escribir self en su código muy a menudo. Si no escribe explícitamente uno mismo, Swift asume que se está refiriendo a una propiedad o método de la instancia actual cada vez que usa una propiedad conocida o nombre de método dentro de un método. Esta suposición se demuestra mediante el uso de count (en lugar de self.count) dentro de los tres métodos de instancia para Counter.

La principal excepción a esta regla se produce cuando un nombre de parámetro para un método de instancia tiene el mismo nombre que una propiedad de esa instancia. En esta situación, el nombre del parámetro tiene prioridad y es necesario referirse a la propiedad de una manera más calificada. Utiliza la propiedad propia para distinguir entre el nombre del parámetro y el nombre de la propiedad.

Aquí, desambigua automáticamente entre un parámetro de método llamado x y una propiedad de instancia que también se llama x:

 struct Point { var x = 0.0, y = 0.0 func isToTheRightOf(x: Double) -> Bool { return self.x > x } } let somePoint = Point(x: 4.0, y: 5.0) if somePoint.isToTheRightOf(x: 1.0) { print("This point is to the right of the line where x == 1.0") } // Prints "This point is to the right of the line where x == 1.0" 

Como dice la documentación de Apple en https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html

La propiedad propia

Cada instancia de un tipo tiene una propiedad implícita llamada self, que es exactamente equivalente a la instancia en sí misma. Utiliza la propiedad de self para referirse a la instancia actual dentro de sus propios métodos de instancia.

El método increment () en el ejemplo anterior podría haberse escrito así:

 func increment() { self.count += 1 } 

En la práctica, no necesita escribir self en su código muy a menudo. Si no escribe explícitamente uno mismo, Swift asume que se está refiriendo a una propiedad o método de la instancia actual cada vez que usa una propiedad conocida o nombre de método dentro de un método. Esta suposición se demuestra mediante el uso de count (en lugar de self.count) dentro de los tres métodos de instancia para Counter.

La principal excepción a esta regla se produce cuando un nombre de parámetro para un método de instancia tiene el mismo nombre que una propiedad de esa instancia. En esta situación, el nombre del parámetro tiene prioridad y es necesario referirse a la propiedad de una manera más calificada. Utiliza la propiedad propia para distinguir entre el nombre del parámetro y el nombre de la propiedad.

Aquí, desambigua automáticamente entre un parámetro de método llamado x y una propiedad de instancia que también se llama x:

 struct Point { var x = 0.0, y = 0.0 func isToTheRightOf(x: Double) -> Bool { return self.x > x } } let somePoint = Point(x: 4.0, y: 5.0) if somePoint.isToTheRightOf(x: 1.0) { print("This point is to the right of the line where x == 1.0") } // Prints "This point is to the right of the line where x == 1.0" 

Sin el prefijo propio, Swift supondría que ambos usos de x se referían al parámetro del método llamado x.

Preferiría seguir usando cada vez que use una propiedad para omitir estos malentendidos.

Como dijo Nick, en el objective-c teníamos ivars + propiedades sintetizadas que daban los nombres de las variables internas para delinear las cosas. P.ej.

 @IBOutlet (nonatomic,strong) UITableView *myTableView; 

lo que _myTableView que _myTableView sea ​​(preferiblemente) referenciado internamente – y self.myTableView para ser referencia más allá de la clase. Si bien es bastante blanco y negro, considere la excepción al crear instancias de vistas mediante progtwigción, puede obtener claridad / simplicidad / reducir el texto repetitivo al eliminarse.

 @interface CustomVC:UIViewController { UITableView *myTableView; } 

Rápidamente, las propiedades públicas / internas aclaran este scope. Si se trata de una propiedad pública, las otras clases interactuarán con la suya propia. De lo contrario, si se salta internamente y evita la repetición automática. El comstackdor lo atrapará cuando sea necesario.

 // UIViewcontroller swift header public var title: String? // Localized title for use by a parent controller. public var navigationItem: UINavigationItem { get } /// In your class self.title = "Clarity" self.navigationItem.leftBarButtonItem = UIBarButtonItem() // In superclass @property(nonatomic, copy) NSString *screenName // use self.screenName in swift subclass @IBOutlet myTableView:UITableView // use self public var myTableView:UITableView // use self internal var myTableView:UITableView // skip self var myTableView:UITableView // skip self