Pregunta

Si una categoría que estoy creando para una clase añade métodos que también cumplen con el contrato establecido por un protocolo, me gustaría bandera que clase de categoría como la implementación del protocolo, y por lo tanto indicar al Obj-C pre- procesador que la clase implementa eficazmente el protocolo también.

Ejemplo delegado (para mayor claridad, gracias Ole!):

@protocol SomeDelegate <NSObject>
  - (void)someDelegateMessage;
@end

Ejemplo categoría:

@interface NSObject (SomeCategory) <SomeDelegate>
  - (void)someDelegateMessage;    
@end

Y con una implementación típica de lo contrario

@implement NSObject (SomeCategory)
  - (void)someDelegateMessage {}
@end

Cuando intento esto en realidad, recibo una advertencia para cada método NSObject:

  

Advertencia: aplicación incompleta de la categoría 'SomeCategory'

     

Advertencia: definición del método de '-Descripción' no encontrado

     

...

     

Advertencia: definición del método de '-isEqual:' no encontrado

     

Advertencia: categoría 'SomeCategory' no implementa completamente el protocolo 'NSObject'

funciona bien si quito <SomeDelegate> de la declaración, pero por supuesto NSObject no se reconoce como un SomeDelegate

¿Fue útil?

Solución

Una solución es declarar el protocolo en una categoría con ninguna implementación, y poner en práctica el método en una categoría diferente, por ejemplo:.

@interface NSObject (SomeCategory) <SomeDelegate>
  - (void)someDelegateMessage;    
@end

@implementation NSObject (SomeCategory_Impl)
  - (void)someDelegateMessage {}
@end

Si lo hace, se considerará que NSObject para ajustarse a <SomeDelegate> en tiempo de compilación, y controles de tiempo de ejecución para someDelegateMessage tendrá éxito. Sin embargo, los controles de tiempo de ejecución conformsToProtocol: fallarán.

Por supuesto, debe reportar un fallo solicitando que los métodos declarados en la clase principal no generan advertencias.

Otros consejos

Hay alguna posibilidad de que su declaración protocolo incluye el protocolo NSObject? De esta manera:

@protocol SomeDelegate <NSObject>
...

Aquí es donde las advertencias provienen de su categoría porque ahora no implementa el protocolo completo. En el código de prueba que acaba de escribir arriba, la eliminación de NSObject del protocolo elimina las advertencias del compilador.

Si desea que el compilador se calle sobre el envío mensajes (y su importante que recuerde que ese es el nombre del protocolo, no es el nombre de la clase), entonces sólo tiene que utilizar variables 'ID', no 'ID' ya que eso le explícitamente diciendo el compilador "Este es un objeto que sólo implementa el protocolo SomeDelegate".

Como alternativa, utilice NSObject como su tipo de variable en lugar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top