Swift Readonly externo, readwrite propiedad interna

En Swift, ¿cuál es la forma convencional de definir el patrón común donde una propiedad debe ser externamente de solo lectura, pero modificable internamente por la clase (y subclases) que la posee?

En Objective-C, existen las siguientes opciones:

  • Declare la propiedad como de solo lectura en la interfaz y use una extensión de clase para acceder a la propiedad internamente. Este es un acceso basado en mensajes, por lo tanto, funciona muy bien con KVO, atomicidad, etc.
  • Declare la propiedad como de solo lectura en la interfaz, pero acceda internamente al respaldo ivar. Como el acceso predeterminado para un ivar está protegido, esto funciona muy bien en una jerarquía de clases, donde las subclases también podrán modificar el valor, pero el campo es de otro modo de solo lectura.

En Java, la convención es:

  • Declare un campo protegido e implemente un getter (método) público de solo lectura.

¿Cuál es el modismo para Swift?

Dada una propiedad de clase, puede especificar un nivel de acceso diferente prefijando la statement de propiedad con el modificador de acceso seguido de get o set entre paréntesis. Por ejemplo, una propiedad de clase con un getter público y un setter privado se declarará como:

 private(set) public var readonlyProperty: Int 

Lectura sugerida: Getters y Setters

Las consideraciones de Martin sobre el nivel de accesibilidad siguen siendo válidas, es decir, no hay ningún modificador protected , el internal restringe el acceso solo al módulo, el private al archivo actual solamente y el public sin restricciones.

Swift 3 notas

Se han agregado 2 nuevos modificadores de acceso, fileprivate y open al idioma, mientras que los private y public se han modificado ligeramente:

  • open aplica a los miembros de la clase y de la clase: se usa para permitir que una clase sea subclasificada o que un miembro sea anulado fuera del módulo donde están definidos. public cambio hace que la clase o el miembro sea públicamente accesible, pero no heredable ni anulable

  • private ahora hace que un miembro sea visible y accesible solo a partir de la statement fileprivate , mientras que fileprivate a todo el archivo donde está contenido

Más detalles aquí .

Según @Antonio, podemos usar una única propiedad para acceder como el valor de propiedad readOnly públicamente y readWrite privada. A continuación está mi ilustración:

 class MyClass { private(set) public var publicReadOnly: Int = 10 //as below, we can modify the value within same class which is private access func increment() { publicReadOnly += 1 } func decrement() { publicReadOnly -= 1 } } let object = MyClass() print("Initial valule: \(object.publicReadOnly)") //For below line we get the compile error saying : "Left side of mutating operator isn't mutable: 'publicReadOnly' setter is inaccessible" //object.publicReadOnly += 1 object.increment() print("After increment method call: \(object.publicReadOnly)") object.decrement() print("After decrement method call: \(object.publicReadOnly)") 

Y aquí está el resultado:

  Initial valule: 10 After increment method call: 11 After decrement method call: 10