¿Cuál es la palabra clave ‘abierta’ en Swift?

El archivo ObjectiveC.swift de la biblioteca estándar contiene las siguientes líneas de código alrededor de la línea 228:

 extension NSObject : Equatable, Hashable { /// ... open var hashValue: Int { return hash } } 

¿Qué significa open var en este contexto, o qué es la palabra clave open en general?

open es un nuevo nivel de acceso en Swift 3, presentado con la implementación de

  • SE-0117 Permitir distinguir entre acceso público y sobrerreabilidad pública

Está disponible con la instantánea de Swift 3 del 7 de agosto de 2016 y con Xcode 8 beta 6.

En breve:

  • Una clase open es accesible y subclassable fuera del módulo de definición. Un miembro de clase open es accesible y reemplazable fuera del módulo de definición.
  • Una clase public es accesible pero no subclassable fuera del módulo de definición. Se puede acceder a un miembro de la clase public pero no se puede sobrepasar el límite fuera del módulo de definición.

Tan open es lo que solía ser el público en versiones previas de Swift y el acceso del public ha sido restringido. O, como dice Chris Lattner en SE-0177: Permitir distinguir entre acceso público y sobrerreabilidad pública :

“Abrir” ahora es simplemente “más público que público”, proporcionando un modelo muy simple y limpio.

En su ejemplo, open var hashValue es una propiedad a la que se puede acceder y puede NSObject en NSObject subclases de NSObject .

Para obtener más ejemplos y detalles, eche un vistazo a SE-0117 .

Open es un nivel de acceso, fue introducido para imponer limitaciones en la herencia de clase en Swift.

Esto significa que el nivel de acceso abierto solo se puede aplicar a clases y miembros de la clase .

En clases

Una clase abierta se puede subclasificar en el módulo en el que está definida y en los módulos que importan el módulo en el que se define la clase.

En clase Miembros

Lo mismo aplica a los miembros de la clase. Un método abierto puede ser anulado por subclases en el módulo en el que está definido y en los módulos que importan el módulo en el que se define el método.

LA NECESIDAD DE ESTA ACTUALIZACIÓN

Algunas clases de bibliotecas y marcos no están diseñados para ser subclasificados y hacerlo puede provocar un comportamiento inesperado. La biblioteca nativa de Apple tampoco permitirá anular los mismos métodos y clases,

Entonces, después de esta adición, aplicarán niveles de acceso públicos y privados en consecuencia.

Para obtener más detalles, consulte la documentación de Apple sobre control de acceso

Leer abierto como

abierto para herencia en otros módulos

Repito abierto para herencia en otros módulos. Entonces, una clase abierta está abierta para subclases en otros módulos que incluyen el módulo de definición. Las variables abiertas y las funciones están abiertas para sobrescribir en otros módulos. Es el nivel de acceso menos restrictivo. Es tan bueno como el acceso público aceptar que algo que es público está cerrado por herencia en otros módulos.

De Apple Docs :

El acceso abierto se aplica solo a las clases y miembros de la clase, y difiere del acceso público de la siguiente manera:

  1. Las clases con acceso público, o cualquier nivel de acceso más restrictivo, se pueden subclasificar solo dentro del módulo donde están definidas.

  2. Los miembros de la clase con acceso público, o cualquier nivel de acceso más restrictivo, pueden ser reemplazados por subclases solo dentro del módulo donde están definidos.

  3. Las clases abiertas se pueden subclasificar dentro del módulo donde están definidas, y dentro de cualquier módulo que importe el módulo donde están definidas.

  4. Los miembros de clase abierta pueden ser reemplazados por subclases dentro del módulo donde están definidos, y dentro de cualquier módulo que importe el módulo donde están definidos.

A excepción de la subclase, también se puede acceder a un open class func desde cualquier lugar de su proyecto. Digamos que está definiendo una función de clase abierta en su clase Util como esta

 open class Utils: NSObject { open class func printHello() { print("Hello from utils") } } 

Luego, en cualquier lugar de sus controladores de vista, puede simplemente acceder a este método llamando

 Utils.printHello()