Soppressione degli avvisi obsoleti in Xcode


133

Con tutti gli SDK in circolazione, è utile poter costruire per più SDK e piattaforme. Tuttavia, rimbalzando da 3.2 a 3.0 e anche occasionalmente 2.x, ricevo spesso avvisi deprecati che riguardano metodi che sono stati modificati o sostituiti:

warning: 'UIKeyboardBoundsUserInfoKey' is deprecated.

Dal momento che voglio ancora mantenere la compatibilità con i sistemi operativi precedenti e mi sto anche sforzando di rimuovere il "rumore" durante la creazione, c'è un modo per disattivare o disabilitare questi avvisi?


4
Mentre la risposta di Paul R funziona, considera che manicaesar è un po 'più chirurgico, in quanto ti consente di sopprimere esattamente l'avvertimento che desideri, senza perdere altri avvisi aggiuntivi che potrebbero essere importanti. Mi sembra che, in termini di migliori pratiche, manicaesar abbia The Correct Answer ™
Olie

Risposte:


82

Prova -Wno-deprecated-declarations, o l'impostazione corrispondente in Xcode, GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS(suggerimento professionale: digita "deprecato" nelle impostazioni di generazione per trovare l'impostazione specifica per questo avviso).

Versioni attuali di Xcode (ad es. Xcode 9.2):

inserisci qui la descrizione dell'immagine


Antiche versioni di Xcode (ad es. Xcode 2.x, 3.x):

inserisci qui la descrizione dell'immagine


17
Si scopre che è ancora più facile di così; c'è una casella di controllo nelle impostazioni di destinazione Xcode; la tua risposta mi ha spinto a cercare lì. Grazie!
Ben Gottlieb,

4
Puoi anche farlo su una base per file. Vedere questa risposta per l'aggiunta di bandiere per file: stackoverflow.com/a/6658549/272473
MrWalker

4
risposte come questa sono frustranti per i neofiti. Provalo dove? Come trovo le impostazioni di destinazione? Una spiegazione in più aumenterebbe il valore di questa risposta.
Noogrub,

8
Una risposta così poco spiegata non dovrebbe essere contrassegnata come corretta.
Chris Hatton,

6
Cerca "Obsoleto" nelle impostazioni della build e lo vedrai.
quantumpotato,

337

Dal momento che non riesco ancora ad aggiungere un commento al post @samiq, penso che lo espanderò. Immettere la direttiva menzionata prima di una funzione / metodo in cui si utilizzano elementi obsoleti. Quindi è possibile ripristinare l'impostazione precedente dopo la definizione della fine della funzione:

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

1
Eccellente! Questo è quello che stavo cercando +1 :)
Zoran Simic

1
Suggerimento fantastico! Peccato che non possa essere dichiarato all'interno di un metodo.
Dustin,

12
In realtà può essere dichiarato all'interno di un metodo. Ho dovuto farlo oggi a causa di un bug in docs / sdk
jer

6
+1 Un modo leggermente migliore è usare la sintassi con #pragma GCC diagnostics push #pragma GCC diagnostics ignored "-Wdeprecated-declarations" .. .. Code here .. .. #pragma GCC diagnostic pop come questo metodo ti riporta a qualunque impostazione fosse stata impostata prima .. [ gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html]
Niclas

3
Modificato in base ai suggerimenti :)
manicaesar il

143

Clang offre una bella funzionalità che rende il passaggio di "ripristino" nel post @manicaesar indipendente dallo stato di avviso iniziale:

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

Per citare il manuale di Clang :

Oltre a tutte le funzionalità fornite dal pragma di GCC, Clang consente anche di inserire e visualizzare lo stato di avviso corrente. Ciò è particolarmente utile quando si scrive un file di intestazione che verrà compilato da altre persone, perché non si sa con quali flag di avvertimento costruiscono.


1
Le versioni più recenti di GCC utilizzano la stessa sintassi (clang sostitutivo di GCC).
Niclas,

3
Mi confondo sempre cosa sono LLVM, GCC e Clang. Quindi, volevo lasciare una nota per risparmiare tempo. GNU Complier Collection (GCC) è stato utilizzato con Xcode 3, quindi Apple ha rilasciato Xcode 4 con un LLVM-GCC ibrido. Quindi il compilatore LLVM (Low Level Virtual Machine) ha preso il controllo, vedi maggiori informazioni su llvm.org . A partire da Xcode 7.2.1 il compilatore predefinito è Apple LLVM 7.0. Il compilatore LLVM è una libreria di altri "progetti", debugger e altri strumenti, che include il compilatore nativo Clang. Clang è un compilatore C / C ++ / Objective-C "nativo LLVM".
serge-k,

42

Dato che tendiamo a dover supportare i vecchi sistemi operativi, ma prestiamo attenzione ai nostri avvisi, volevo un modo più ordinato per farlo. L'ho messo insieme, ispirato ad un codice 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)

Questo ti permette di fare quanto segue:

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

Funziona anche con blocchi di codice:

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

Inoltre, quando si elimina il supporto per i dispositivi precedenti a iOS 7, è possibile cercare facilmente il codice per trovare gli usi obsoleti da correggere.


questa è una soluzione a lungo termine molto migliore per la maggior parte del codice rispetto alla repressione degli avvisi di deprecazione (o di qualsiasi altro) a livello globale / di progetto. risposta formidabile.
natbro,

1
Perché è do { ... } while(0);richiesto?
Ben Leggiero,

1
@ BenC.R.Leggiero perché non stai passando un blocco ma diverse affermazioni tra quelle parentesi. Stai praticamente sopprimendo gli avvisi per ogni riga.
Alejandro Iván,

1
@ AlejandroIván So che la tua spiegazione ha senso per te ... ma per me sembra proprio che tu stia riformulando la domanda. Puoi spiegare perché do{...}while(0);è richiesto qui in particolare? Perché non solo {...}? Perché no if(true){...}? ecc.
Ben Leggiero,

2
@ BenC.R.Leggiero hai ragione. Per qualche ragione ho letto male la tua domanda. Controlla qui la risposta accettata: stackoverflow.com/questions/154136/…
Alejandro Iván

29

Puoi anche eliminare gli avvisi per file utilizzando

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

che a sua volta rende un po 'meglio la pratica che sopprimere tutti gli avvertimenti una volta e tutte insieme ... dopo tutto hai avuto modo di sapere per cosa lo stai facendo.


20

Se si desidera silenziare l'avviso Implementazione del metodo obsoleto o Implementazione della classe obsoleta , utilizzare:

    #pragma clang push diagnostico
    #pragma clang diagnostics ignorato "-Wdeprecated-implementations"
    // codice
    #pragma clang pop diagnostico


Quando ho visto "-Wdeprecated-dichiarazioni", immagino che ci debbano essere "-Wdeprecated-implementations". E funziona davvero. Grazie.
DawnSong,

8

Nelle impostazioni della build, trova Deprecated Functions.

inserisci qui la descrizione dell'immagine


Chiuderà tutti gli avvisi "obsoleti", tuttavia è necessario eliminare solo alcuni avvisi.
DawnSong,

2

Se desideri una coperta, controlla tutti i tipi di ammortamenti in un pezzo di codice. Si prega di utilizzare il flag -Wdeprecated come di seguito:

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

-3

Per disabilitare l'avviso dal file di intestazione di terze parti, aggiungere la seguente riga nella parte superiore del file

#pragma clang system_header
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.