protocolos multiple herencia swift swift2

multiple - protocolos swift



¿Cómo almaceno los datos enviados a las propiedades calculadas en una extensión de protocolo? (2)

Extensión de protocolo? ¿Por qué?

A veces nos obsesionamos tanto con una idea que ignoramos una solución práctica que nos mira directamente a la cara.

1. ¿Tiene un conjunto de propiedades calculadas? No, quieres propiedades almacenadas.

Dado que todas estas clases deberían tener las mismas propiedades calculadas, y dado que las propiedades deberían comportarse de manera idéntica en diferentes clases ...

... pero despues

El problema es que una extensión no es compatible con las propiedades almacenadas. ¿Pero dónde / cómo guardo los datos enviados a las propiedades calculadas?

2. Suponiendo que es un conjunto de propiedades almacenadas que desea, ¡prácticamente usted mismo proporcionó la solución! Hizo un cambio que tendrá sentido ahora.

Podría transformar la extensión en una clase que implemente SomeProtocol y luego convertir SomeClass en una subclase. Eso me permitiría guardar los datos en las propiedades almacenadas.

Extiende la clase siempre que lo desee y luego confirma sus subclases a SomeProtocol para obtener las características. Esto es más limpio.

En una nota lateral, los protocolos de Swift que no pueden almacenar propiedades son por diseño. Los protocolos no tienen existencia por derecho propio y no tiene sentido agregar propiedades almacenadas en ellos.

En la aplicación en la que estoy trabajando actualmente, trato de aprovechar la nueva función de extensión de protocolo en Swift. La idea es que tengo muchas clases implementando el mismo protocolo. Dado que todas estas clases deberían tener las mismas propiedades calculadas, y dado que las propiedades deberían comportarse de manera idéntica en diferentes clases, pensé que sería bueno agregar la funcionalidad solo una vez.

Mi código está estructurado como el siguiente ejemplo

protocol SomeProtocol { ... } // There could potentially be unlimited different versions of "SomeClass" that implements "SomeProtocol" class SomeClass : SomeProtocol { ... } extension SomeProtocol { var computedProperty1: Type? { get { getData(SOME_ENUM) } set { validateAndSave(newValue, atKey: SOME_ENUM) } } var computedProperty2: Type? { get { getData(SOME_OTHER_ENUM) } set { validateAndSave(newValue, atKey: SOME_OTEHR_ENUM) } } ... func getData(atKey: ENUM_TYPE) -> Type? { [NEED SOME WAY TO GET THE SAVED DATA AND RETURN IT] } func validateAndSave(value: Type?, atKey: ENUM_TYPE) { [NEED SOME WAY TO SAVE DATA FOR LATER RETURNING] } } // The properties needs to be visible to the client code like this: class ClientCode { let someClassObject: SomeProtocol = SomeClass() someClassObject.computedProperty1 = Type() print(someClassObject.computedProperty1) }

(El código anterior muestra signos de almacenar los datos en diferentes diccionarios, que fue mi primer pensamiento)

El problema es que una extensión no es compatible con las propiedades almacenadas. ¿Pero dónde / cómo guardo los datos enviados a las propiedades calculadas?

Puedo pensar en 2 soluciones diferentes, pero ninguna de ellas es buena ...

  1. Podría transformar la extensión en una clase que implemente SomeProtocol y luego convertir SomeClass una subclase. Eso me permitiría guardar los datos en las propiedades almacenadas. Pero también me obligaría a implementar todos los métodos que requiere el protocolo en la nueva clase, y eso no tiene ningún sentido, ya que son las diferentes versiones de SomeClass que deberían proporcionar una funcionalidad diferente.
  2. Podría simplemente descartar toda la idea de extensión y mover todas las propiedades a SomeProtocol . Pero eso requeriría implementar todas las propiedades calculadas en todas las diferentes versiones de SomeClass con funcionalidades idénticas, y el objetivo de mi idea de extensión era evitar escribir la misma implementación para las mismas propiedades una y otra vez.

¿Hay alguna solución lógica completamente fácil que he pasado por alto?

... o una buena manera de guardar datos en una extensión de protocolo que no conozco?

... u otra forma de obtener la funcionalidad deseada?

... o debería simplemente aspirar y usar una de mis soluciones no tan bonitas?


Suponiendo que entiendo la pregunta correctamente para evitar el hecho de que las extensiones de protocolo no son compatibles con las propiedades almacenadas, podría extender NSObject y usar el tiempo de ejecución C objetivo para almacenar sus propiedades.

import ObjectiveC private var AssociationKey: UInt8 = 0 class YourStoredObject { // Whatever object your are persisting } extension NSObject { var yourStoredObject: (YourStoredObject)! { get { return objc_getAssociatedObject(self, &AssociationKey) as? YourStoredObject } set(newValue) { objc_setAssociatedObject(self, &AssociationKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) } } } protocol YourProtocol { var yourStoredObject: YourStoredObject! { get set } } extension YourProtocol { func customYourStoredObjectGetter() -> YourStoredObject { return yourStoredObject } } extension UILabel : YourProtocol { func myExtendedFunc() { // Get (and print) your object directly print(yourStoredObject) // Get your object through a protocol custom getter print(customYourStoredObjectGetter()) // Set your object yourStoredObject = YourStoredObject() } }

No digo que esta sea la mejor solución, pero esta es la única solución que se me ocurre. También estoy buscando alternativas Swift más agradables, pero todavía no he encontrado ninguna.