Suprimindo avisos descontinuados no Xcode

133

Com todos os SDKs flutuando, é útil poder construir para vários SDKs e plataformas. No entanto, saltando de 3,2 para 3,0 e até ocasionalmente para o 2.x, frequentemente recebo avisos preteridos envolvendo métodos que foram alterados ou substituídos:

warning: 'UIKeyboardBoundsUserInfoKey' is deprecated.

Como ainda quero manter a compatibilidade com sistemas operacionais mais antigos, e também estou tentando remover o 'ruído' ao criar, existe uma maneira de desativar ou desativar esses avisos?

Ben Gottlieb
fonte
4
Enquanto a resposta de Paul R funciona, considere que manicaesar é um pouco mais cirúrgico, pois permite suprimir exatamente o aviso desejado, sem perder outros avisos adicionais que possam ser importantes. Parece-me que, em termos de melhores práticas, manicaesar tem a resposta correta ™
Olie

Respostas:

82

Tente -Wno-deprecated-declarations, ou sua configuração correspondente no Xcode, GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS(dica profissional: digite "obsoleto" nas configurações de compilação para encontrar a configuração específica para este aviso).

Versões atuais do Xcode (por exemplo, Xcode 9.2):

insira a descrição da imagem aqui


Versões antigas do Xcode (por exemplo, Xcode 2.x, 3.x):

insira a descrição da imagem aqui

Paul R
fonte
17
Acontece que é ainda mais fácil do que isso; há uma caixa de seleção nas configurações de destino do Xcode; sua resposta me levou a procurar lá. Obrigado!
Ben Gottlieb
4
Você também pode fazer isso por arquivo. Veja esta resposta para adicionar sinalizadores por arquivo: stackoverflow.com/a/6658549/272473
mrwalker
4
respostas como essa são frustrantes para os novatos. Experimente onde? Como encontro as configurações de destino? Um pouco mais de explicação aumentaria o valor dessa resposta.
noogrub
8
Uma resposta que este mal explicado não deve ser marcada como correta.
Chris Hatton
6
Pesquise "Descontinuado" nas configurações de compilação e você verá.
Quantumpotato
337

Como ainda não consigo adicionar um comentário ao post @samiq, acho que o expandirei. Diretiva de entrada mencionada antes de uma função / método no qual você usa itens obsoletos. Em seguida, você pode restaurar a configuração anterior após a definição da função final:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma GCC diagnostic pop
manicaesar
fonte
1
Excelente! Isto é o que eu estava procurando uma :)
Zoran Simic
1
Dica incrível! Pena que não pode ser declarado dentro de um método.
Dustin
12
Na verdade, pode ser declarado dentro de um método. Eu apenas tive que fazê-lo hoje, devido um erro no docs / SDK
Jer
6
+1 Uma maneira um pouco melhor é usar a sintaxe, #pragma GCC diagnostics push #pragma GCC diagnostics ignored "-Wdeprecated-declarations" .. .. Code here .. .. #pragma GCC diagnostic pop pois esse método o leva de volta para qualquer configuração que tenha sido definida anteriormente. [ Gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html]
Niclas
3
Mudou monitores segundo a sugestões :)
manicaesar
143

O Clang fornece um recurso interessante que torna a etapa "restore" no post do @manicaesar independente do estado de aviso inicial:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma clang diagnostic pop

Para citar o manual Clang :

Além de todas as funcionalidades fornecidas pelo pragma do GCC, o Clang também permite que você pressione e salte o estado de aviso atual. Isso é particularmente útil ao escrever um arquivo de cabeçalho que será compilado por outras pessoas, porque você não sabe com quais sinalizadores de aviso eles constroem.

Andrew Hershberger
fonte
1
Versões mais recentes do GCC usam a mesma sintaxe (clang substituto para o GCC).
Niclas
3
Eu sempre fico confuso sobre o que é LLVM, GCC e Clang. Então, eu queria soltar uma nota para economizar tempo. A GNU Complier Collection (GCC) foi usada com o Xcode 3, e a Apple lançou o Xcode 4 com um LLVM-GCC híbrido. Em seguida, o compilador LLVM (Low Level Virtual Machine) assumiu o comando, veja mais informações em llvm.org . No Xcode 7.2.1, o compilador padrão é o Apple LLVM 7.0. O compilador LLVM é uma biblioteca de outros "projetos", depuradores e outras ferramentas, que incluem o compilador nativo Clang. Clang é um compilador C / C ++ / Objective-C "nativo LLVM".
Serge-k
42

Como tendemos a precisar oferecer suporte a sistemas operacionais mais antigos, mas preste atenção aos nossos avisos, eu queria uma maneira mais organizada de fazer isso. Eu montei isso, inspirado em algum código Mozilla:

#define SILENCE_DEPRECATION(expr)                                   \
do {                                                                \
_Pragma("clang diagnostic push")                                    \
_Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")   \
expr;                                                               \
_Pragma("clang diagnostic pop")                                     \
} while(0)

#define SILENCE_IOS7_DEPRECATION(expr) SILENCE_DEPRECATION(expr)
#define SILENCE_IOS8_DEPRECATION(expr) SILENCE_DEPRECATION(expr)

Isso permite que você faça o seguinte:

SILENCE_IOS7_DEPRECATION(return [self sizeWithFont:font constrainedToSize:size]);

Também funciona com blocos de código:

SILENCE_IOS7_DEPRECATION(
    view = [[MKPolylineView alloc] initWithPolyline:self];
    view.lineWidth = self.lineWidth;
    view.strokeColor = self.color;
);

Além disso, quando você dispensa o suporte a dispositivos anteriores ao iOS 7, pode pesquisar facilmente o código para encontrar os usos obsoletos a serem corrigidos.

Joe Hughes
fonte
essa é a solução a longo prazo muito melhor para a maioria dos códigos do que reprimir avisos de descontinuação (ou qualquer outro) em nível global / de projeto. resposta fantástica.
Nat1 #
1
Por que é do { ... } while(0);necessário?
Ben Leggiero 15/03/19
1
@ BenC.R.Leggiero porque você não está passando um bloco, mas várias instruções entre esses parênteses. Você está basicamente suprimindo avisos para cada linha.
Alejandro Iván
1
@ AlejandroIván Eu sei que sua explicação faz sentido para você ... mas para mim, parece que você está reformulando a pergunta. Você pode explicar por que do{...}while(0);é necessário aqui em particular? Por que não apenas {...}? Por que não if(true){...}? etc.
Ben Leggiero 12/04
2
@ BenC.R.Leggiero você está certo. Por alguma razão, interpretei mal sua pergunta. Verifique a resposta aceita aqui: stackoverflow.com/questions/154136/…
Alejandro Iván
29

Você também pode suprimir avisos por arquivo usando

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

o que, por sua vez, torna uma prática um pouco melhor do que apenas suprimir todos os avisos de uma vez por todas ... afinal você precisa saber para que está fazendo isso.

samiq
fonte
20

Se você deseja silenciar o aviso Implementando Método Preterido ou Implementando Classe Preterida , use:

    push de diagnóstico #pragma clang
    diagnóstico de #pragma clang ignorado "-Wdeprecated-implementations"
    // código
    #pragma clang diagnostic pop

krzysztof
fonte
Quando vi "-Wdeprecated-declarações", acho que deve haver "-Wdeprecated-implementations". E isso realmente funciona. Obrigado.
DawnSong
8

Nas configurações de sua compilação, encontre Deprecated Functions.

insira a descrição da imagem aqui

Olá Mundo
fonte
Ele fechará todos os avisos "obsoletos"; no entanto, apenas alguns avisos precisam ser suprimidos.
DawnSong
2

Se você desejar uma verificação geral, verifique todos os tipos de deprecações em um pedaço de código. Use o sinalizador -Wdeprecated como abaixo:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma clang diagnostic pop
jarora
fonte
-3

Para desativar o aviso do arquivo de cabeçalho de terceiros, adicione a seguinte linha na parte superior do arquivo

#pragma clang system_header
harvestli
fonte