Pergunta

Se uma categoria que estou criando para uma classe adiciona métodos que também cumprem o contrato estabelecido por um protocolo, gostaria de sinalizar essa classe de categoria como implementando o protocolo e, assim, indicar ao pré-processador Obj-C que o class também implementa efetivamente o protocolo.

Exemplo de delegado (para maior clareza, obrigado Ole!):

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

Categoria de exemplo:

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

E com uma implementação típica

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

Quando tento fazer isso, recebo um aviso para cada método NSObject:

aviso:implementação incompleta da categoria 'SomeCategory'

aviso:definição de método para '-descrição' não encontrada

...

aviso:definição de método para '-isEqual:' não encontrada

aviso:a categoria 'SomeCategory' não implementa totalmente o protocolo 'NSObject'

Funciona bem se eu remover <SomeDelegate> da declaração, mas é claro que NSObject não é reconhecido como SomeDelegate

Foi útil?

Solução

Uma solução alternativa é declarar o protocolo em uma categoria sem implementação e implementar o método em uma categoria diferente, por exemplo:

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

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

Se você fizer isto, NSObject será considerado em conformidade com <SomeDelegate> no momento da compilação e verificações de tempo de execução para someDelegateMessage terá sucesso. No entanto, conformsToProtocol: As verificações de tempo de execução falharão.

Claro, você deveria arquivar um bug Solicitar que os métodos declarados na classe principal não gerem avisos.

Outras dicas

Qualquer chance de sua declaração de protocolo incluir o NSObject protocolo? Assim:

@protocol SomeDelegate <NSObject>
...

É daí que vêm os avisos, porque agora sua categoria não implementa o protocolo completo. No código de teste que acabei de digitar, removendo NSObject Do protocolo remove os avisos do compilador.

Se você quiser que o compilador cale a boca sobre o envio de mensagens <NSObject> (e é importante que você lembre que esse é o nome do protocolo, não o nome da classe), então apenas use variáveis ​​'id', não 'id', já que você está dizendo explicitamente ao compilador "Este é um objeto que implementa apenas o protocolo SomeDelegate".

Como alternativa, use NSObject como tipo de variável.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top