Suppression des avertissements obsolètes dans Xcode

133

Avec tous les SDK flottants, il est pratique de pouvoir créer pour plusieurs SDK et plates-formes. Cependant, en passant de la 3.2 à la 3.0 et même occasionnellement à la 2.x, je reçois fréquemment des avertissements obsolètes impliquant des méthodes qui ont changé ou ont été remplacées:

warning: 'UIKeyboardBoundsUserInfoKey' is deprecated.

Étant donné que je souhaite toujours maintenir la compatibilité avec les anciens systèmes d'exploitation et que je m'efforce également de supprimer le «bruit» lors de la construction, existe-t-il un moyen de désactiver ou de désactiver ces avertissements?

Ben Gottlieb
la source
4
Bien que la réponse de Paul R fonctionne, considérez que le manicaesar est un peu plus chirurgical, en ce sens qu'il vous permet de supprimer exactement l'avertissement souhaité, sans perdre d'autres avertissements supplémentaires qui pourraient être importants. Il me semble que, en termes de bonnes pratiques, manicaesar a The Correct Answer ™
Olie

Réponses:

82

Essayez -Wno-deprecated-declarations, ou son paramètre correspondant dans Xcode, GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS(conseil de pro: tapez simplement "obsolète" dans les paramètres de construction pour trouver le paramètre spécifique pour cet avertissement).

Versions actuelles de Xcode (par exemple Xcode 9.2):

entrez la description de l'image ici


Anciennes versions de Xcode (par exemple Xcode 2.x, 3.x):

entrez la description de l'image ici

Paul R
la source
17
Il s'avère que c'est encore plus facile que cela; il y a une case à cocher dans les paramètres de la cible Xcode; votre réponse m'a incité à chercher là-bas. Merci!
Ben Gottlieb
4
Vous pouvez également le faire sur une base par fichier. Voir cette réponse pour ajouter des indicateurs par fichier: stackoverflow.com/a/6658549/272473
mrwalker
4
des réponses comme celle-ci sont frustrantes pour les novices. Essayez-le où? Comment trouver les paramètres cibles? Un peu plus d'explication augmenterait la valeur de cette réponse.
noogrub
8
Une réponse mal expliquée ne doit pas être marquée comme correcte.
Chris Hatton
6
Recherchez «Obsolète» dans les paramètres de compilation et vous le verrez.
quantumpotato
337

Comme je ne peux pas encore ajouter de commentaire au post @samiq, je pense que je vais le développer. Entrez la directive mentionnée avant une fonction / méthode dans laquelle vous utilisez des éléments obsolètes. Ensuite, vous pouvez restaurer le paramètre précédent après la fin de la définition de la fonction:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma GCC diagnostic pop
manicaesar
la source
1
Excellent! C'est ce que je cherchais +1 :)
Zoran Simic
1
Astuce géniale! Dommage qu'il ne puisse pas être déclaré dans une méthode.
Dustin
12
En fait, il peut être déclaré dans une méthode. Je devais juste le faire aujourd'hui à cause d'un bug dans la documentation / sdk
jer
6
+1 Une manière légèrement meilleure consiste à utiliser la syntaxe avec #pragma GCC diagnostics push #pragma GCC diagnostics ignored "-Wdeprecated-declarations" .. .. Code here .. .. #pragma GCC diagnostic pop car cette méthode vous ramène au paramètre défini auparavant. [ Gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html]
Niclas
3
Changé selon les suggestions :)
manicaesar
143

Clang fournit une fonctionnalité intéressante qui rend l'étape de "restauration" dans le post @manicaesar indépendante de l'état d'avertissement initial:

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

Pour citer le manuel Clang :

En plus de toutes les fonctionnalités fournies par le pragma de GCC, Clang vous permet également de pousser et d'afficher l'état d'avertissement actuel. Ceci est particulièrement utile lors de l'écriture d'un fichier d'en-tête qui sera compilé par d'autres personnes, car vous ne savez pas avec quels indicateurs d'avertissement ils construisent.

Andrew Hershberger
la source
1
Les versions plus récentes de GCC utilisent la même syntaxe (remplace Clang pour GCC).
Niclas
3
Je suis toujours confus sur ce que sont LLVM, GCC et Clang. Donc, je voulais déposer une note pour gagner du temps. GNU Complier Collection (GCC) a été utilisé avec Xcode 3, puis Apple a publié Xcode 4 avec un LLVM-GCC hybride. Ensuite, le compilateur LLVM (Low Level Virtual Machine) a pris le relais, voir plus d'informations sur llvm.org . Depuis Xcode 7.2.1, le compilateur par défaut est Apple LLVM 7.0. Le compilateur LLVM est une bibliothèque d'autres «projets», débogueurs et autres outils, qui incluent le compilateur natif Clang. Clang est un compilateur C / C ++ / Objective-C "LLVM natif".
serge-k
42

Comme nous avons tendance à avoir besoin de prendre en charge des systèmes d'exploitation plus anciens, mais faites attention à nos avertissements, je voulais une façon plus ordonnée de le faire. J'ai mis cela ensemble, inspiré par du code 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)

Cela vous permet d'effectuer les opérations suivantes:

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

Cela fonctionne également avec des blocs de code:

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

En outre, lorsque vous supprimez la prise en charge des appareils pré-iOS 7, vous pouvez facilement rechercher dans le code pour trouver les utilisations obsolètes à corriger.

Joe Hughes
la source
c'est une bien meilleure solution à long terme pour la plupart du code que de restreindre les avertissements d'obsolescence (ou tout autre) au niveau global / projet. excellente réponse.
natbro
1
Pourquoi le do { ... } while(0);requis?
Ben Leggiero
1
@ BenC.R.Leggiero parce que vous ne passez pas un bloc mais plusieurs instructions entre ces parenthèses. Vous supprimez essentiellement les avertissements pour chaque ligne.
Alejandro Iván
1
@ AlejandroIván Je sais que votre explication a du sens pour vous ... mais pour moi, il semble que vous reformulez la question. Pouvez-vous expliquer pourquoi do{...}while(0);est requis ici en particulier? Pourquoi pas juste {...}? Pourquoi pas if(true){...}? etc.
Ben Leggiero
2
@ BenC.R.Leggiero vous avez raison. Pour une raison quelconque, j'ai mal lu votre question. Vérifiez la réponse acceptée ici: stackoverflow.com/questions/154136/…
Alejandro Iván
29

Vous pouvez également supprimer les avertissements par fichier en utilisant

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

ce qui en fait une pratique un peu meilleure que de simplement supprimer tous les avertissements une fois et ensemble ... après tout, vous devez savoir pourquoi vous le faites.

samiq
la source
20

Si vous souhaitez désactiver l'avertissement Implémentation d'une méthode obsolète ou Implémentation d'une classe obsolète , utilisez:

    #pragma clang diagnostic push
    #pragma clang diagnostic ignoré "-Wdeprecated-implementations"
    // code
    #pragma clang diagnostic pop

krzysztof
la source
Quand j'ai vu "-Wdeprecated-declarations", je suppose qu'il doit y avoir "-Wdeprecated-implementations". Et ça marche vraiment. Je vous remercie.
DawnSong
8

Dans vos paramètres de construction, recherchez Deprecated Functions.

entrez la description de l'image ici

Bonjour le monde
la source
Il fermera tous les avertissements «obsolètes», cependant, seuls certains avertissements doivent être supprimés.
DawnSong
2

Si vous souhaitez une vérification globale de toutes sortes d'obsolescence dans un morceau de code. Veuillez utiliser le drapeau -Wdeprecated comme ci-dessous:

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

Pour désactiver l'avertissement du fichier d'en-tête tiers, ajoutez la ligne suivante en haut du fichier

#pragma clang system_header
Harvestli
la source