2011-05-05 12 views
26

El Escenario
Tengo una situación en la que una clase base llamada AbstractRequest tiene una propiedad delegado de tipo id <AbstractRequestDelegate> declarado en el archivo de cabecera:¿Cómo anular la propiedad de una superclase con tipos más específicos?

@property (nonatomic, assign) id <AbstractRequestDelegate> delegate; 

El protocolo delegado abstracta contiene algunos métodos, y como ha se indica con la palabra 'abstracto', tanto el AbstractRequest y la AbstractRequestDelegate están destinados a ser subclases/extendido.

Un ejemplo de esto sería la subclase ConcreteRequest y ConcreteRequestDelegates protocolo extendido, que tanto añadir métodos adicionales para los abstractos. La intención es que tanto los métodos de clase abstractos como los concretos puedan enviar mensajes a la única instancia delegada asignada.

En un cierto punto en el tiempo de la ConcreteRequest quisiera llamar a un método en el delegado que se define por ConcreteRequestDelegate. Como el tipo de delegado es id, el compilador advertirá que este método podría no implementarse.

ConcreteRequest.m: 38: advertencia: propiedad 'delegado' requiere método '-delegate' que definirse - utilizar @synthesize, @dynamic o proporcionar una implementación método

el problema
Esta advertencia se justifica, por la propiedad es, después de todo escrito a id <AbstractRequestDelegate>. Para solucionar esto, quiero dejar en claro para el compilador que el delegado asignado a la instancia concreta debe ser del tipo id <ConcreteRequestDelegate>. Esto sonaba perfectamente razonable para mí, por lo que poner en una nueva propiedad en la cabecera ConcreteRequest, con la esperanza de anular el resumen de una:

@property (nonatomic, assign) id <ConcreteRequestDelegate> delegate; 

Pero aquí es donde el compilador no está de acuerdo conmigo, probablemente con razón. Pensé que daría una advertencia para anular la propiedad de una clase superior con el tipo incorrecto, pero en su lugar solo me exige volver a sintetizar esta nueva propiedad. No quiero ir allí, porque los métodos de la superclase no tendrán acceso a la misma propiedad de delegado.

La pregunta
¿Hay una manera de 'volver a declarar' la propiedad de la subclase concreta con la información de tipo agregado? ¿O puede detectar el error en mi forma de pensar, porque tal vez este es un problema bastante común que no he encontrado hasta ahora?

Cheers,
Ep.

P.S. Todos los nombres de clase y protocolo que aparecen en este trabajo son ficticios. Cualquier parecido con nombres reales de clase y protocolo, de código abierto o patentados, es pura coincidencia.

+2

lol en P.S. : D ... podrías publicar el código para toda la interfaz y clases ... tu explicación es demasiado larga –

+0

Esto ya me ha costado media hora, tal vez alguien más puede ver a través de las muchas palabras. Si todo falla, invertiré el tiempo para pseudocódigo de estas clases. – epologee

+0

: D ¿Por qué crees que volver a sintetizar creará un problema –

Respuesta

11

La advertencia ya se dio la pista derecha. Utilicé @dynamic en la subclase principal y todo está bien.

+1

? ¿Podrías explicar qué hiciste en la subclase para que funcione? también, ¿todavía crees que este es un buen patrón? – shaunlim

+3

Para cualquiera que se encuentre con esto más adelante, lo que esta respuesta está diciendo es que si simplemente redeclara la propiedad en la subclase, efectivamente funciona, pero hay una advertencia. Si luego ingresa en su sección de implementación en su archivo .m y agrega la línea "@dinámica samevariablename", efectivamente causa que la advertencia/problema en la declaración @property desaparezca. No se puede esperar que lo haga porque la advertencia se encuentra en un lugar diferente al lugar donde se resuelve el problema, pero lo hace. Simplemente funcionó para mí también. –

2

Simplemente sintetice id<ConcreteRequestDelegate>delegate en el ConcreteRequest.m, funcionará bien ... No creará ningún problema.

Cuestiones relacionadas