Eu queria saber como suprimir o aviso:
Categoria está implementando um método que também será implementado por sua classe primária.
Eu tenho isso para uma categoria de código específica:
+ (UIFont *)systemFontOfSize:(CGFloat)fontSize {
return [self aCustomFontOfSize:fontSize];
}
objective-c
clang
Doz
fonte
fonte
super
outra forma.Respostas:
Uma categoria permite adicionar novos métodos a uma classe existente. Se você deseja reimplementar um método que já existe na classe, normalmente cria uma subclasse em vez de uma categoria.
Documentação da Apple: Customizando classes existentes
Dois métodos com a mesma assinatura exata na mesma classe levariam a um comportamento imprevisível, porque cada chamador não pode especificar qual implementação deseja.
Portanto, você deve usar uma categoria e fornecer nomes de método que sejam novos e exclusivos para a classe, ou subclasse, se desejar alterar o comportamento de um método existente em uma classe.
fonte
Embora tudo o que foi dito corretamente esteja correto, na verdade não responde à sua pergunta sobre como suprimir o aviso.
Se você precisar inserir esse código por algum motivo (no meu caso, tenho HockeyKit em meu projeto e eles substituem um método em uma categoria UIImage [editar: este não é mais o caso]) e você precisa fazer com que seu projeto seja compilado , você pode usar
#pragma
instruções para bloquear o aviso, como:Encontrei as informações aqui: http://www.cocoabuilder.com/archive/xcode/313767-disable-warning-for-override-in-category.html
fonte
Uma alternativa melhor (veja a resposta de Bneely sobre por que esse aviso está salvando você de um desastre) é usar o método swizzling. Ao usar o método swizzling, você pode substituir um método existente de uma categoria sem a incerteza de quem "vence" e ao mesmo tempo preservando a capacidade de chamar o método antigo. O segredo é dar à substituição um nome de método diferente e trocá-los usando funções de tempo de execução.
Em seguida, defina sua implementação personalizada:
Substitua a implementação padrão pela sua:
fonte
Experimente isso em seu código:
ATUALIZAÇÃO2: Adicionar esta macro
fonte
Você pode usar o método swizzling para suprimir este aviso do compilador. Aqui está como eu implementei o método swizzling para desenhar margens em um UITextField quando usamos um fundo personalizado com UITextBorderStyleNone:
fonte
Propriedades de substituição são válidas para uma extensão de classe (categoria anônima), mas não para uma categoria regular.
De acordo com o Apple Docs, usando uma extensão de classe (categoria anônima), você pode criar uma interface privada para uma classe pública, de forma que a interface privada possa substituir as propriedades expostas publicamente. ou seja, você pode alterar uma propriedade de somente leitura para leitura e gravação.
Um caso de uso para isso é quando você grava bibliotecas que restringem o acesso a propriedades públicas, enquanto a mesma propriedade precisa de acesso total de leitura e gravação dentro da biblioteca.
Link do Apple Docs: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html
Pesquise " Use extensões de classe para ocultar informações privadas ".
Portanto, esta técnica é válida para uma extensão de classe, mas não para uma categoria.
fonte
As categorias são boas, mas podem ser abusadas. Ao escrever categorias, você deve, por princípio, NÃO reimplementar os métodos existentes. Fazer isso pode causar um efeito colateral estranho, já que agora você está reescrevendo código do qual outra classe depende. você pode quebrar uma classe conhecida e acabar virando seu depurador do avesso. É simplesmente uma programação ruim.
Se você precisa fazer isso, você realmente deve subclassificá-lo.
Então a sugestão de swizzling, que é um grande NÃO-NÃO-NÃO para mim.
Swizzing em tempo de execução é um NO-NO-NO completo.
Você quer que uma banana se pareça com uma laranja, mas apenas em tempo de execução? Se você quiser uma laranja, escreva uma laranja.
Não faça uma banana parecer e agir como uma laranja. E pior: não transforme sua banana em um agente secreto que sabotará bananas em todo o mundo em apoio às laranjas.
Caramba!
fonte
Tive esse problema quando implementei um método delegado em uma categoria em vez da classe principal (embora não houvesse implementação da classe principal). A solução para mim foi mover do arquivo de cabeçalho de classe principal para o arquivo de cabeçalho de categoria. Isso funciona bem
fonte