Pomijanie przestarzałych ostrzeżeń w Xcode

134

Ponieważ wszystkie zestawy SDK są dostępne, przydatne jest tworzenie dla wielu zestawów SDK i platform. Jednak przy przeskakiwaniu z wersji 3.2 do 3.0, a nawet czasami od 2.x, często otrzymuję przestarzałe ostrzeżenia dotyczące metod, które zostały zmienione lub zastąpione:

warning: 'UIKeyboardBoundsUserInfoKey' is deprecated.

Ponieważ nadal chcę zachować zgodność ze starszymi systemami operacyjnymi, a także staram się usunąć „szum” podczas budowania, czy istnieje sposób na wyłączenie lub wyłączenie tych ostrzeżeń?

Ben Gottlieb
źródło
4
Chociaż odpowiedź Paula R działa, weź pod uwagę, że manicaesar jest nieco bardziej chirurgiczny, ponieważ pozwala stłumić dokładnie to, czego chcesz, bez utraty innych dodatkowych ostrzeżeń, które mogą być ważne. Wydaje mi się, że pod względem najlepszych praktyk manicaesar ma The Correct Answer ™
Olie

Odpowiedzi:

83

Wypróbuj -Wno-deprecated-declarationslub odpowiadające mu ustawienie w Xcode GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS(wskazówka dla profesjonalistów: po prostu wpisz „przestarzałe” w ustawieniach kompilacji, aby znaleźć określone ustawienie dla tego ostrzeżenia).

Aktualne wersje Xcode (np. Xcode 9.2):

wprowadź opis obrazu tutaj


Starożytne wersje Xcode (np. Xcode 2.x, 3.x):

wprowadź opis obrazu tutaj

Paul R.
źródło
17
Okazuje się, że jest to jeszcze łatwiejsze; w ustawieniach docelowych Xcode jest pole wyboru; Twoja odpowiedź skłoniła mnie do przeszukania tam. Dzięki!
Ben Gottlieb,
4
Możesz to również zrobić dla każdego pliku. Zobacz tę odpowiedź dotyczącą dodawania flag dla poszczególnych plików: stackoverflow.com/a/6658549/272473
mrwalker
4
takie odpowiedzi są frustrujące dla nowicjuszy. Spróbuj gdzie? Jak znaleźć ustawienia docelowe? Nieco więcej wyjaśnień zwiększyłoby wartość tej odpowiedzi.
noogrub
8
Tak słabo wyjaśnionej odpowiedzi nie należy oznaczać jako poprawnej.
Chris Hatton
6
Wyszukaj „Wycofane” w ustawieniach kompilacji, a zobaczysz je.
quantumpotato
338

Ponieważ nie mogę jeszcze dodać komentarza do posta @samiq, myślę, że go rozbuduję. Wprowadź wspomnianą dyrektywę przed funkcją / metodą, w której używasz przestarzałych rzeczy. Następnie możesz przywrócić poprzednie ustawienie po zdefiniowaniu zakończenia funkcji:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma GCC diagnostic pop
manicaesar
źródło
1
Świetny! Właśnie tego szukałem +1 :)
Zoran Simic
1
Świetna wskazówka! Szkoda, że ​​nie można tego zadeklarować wewnątrz metody.
Dustin
12
Właściwie można to zadeklarować wewnątrz metody. Po prostu musiałem to zrobić dzisiaj z powodu błędu w dokumentacji / sdk
jer
6
+1 Nieco lepszym sposobem jest użycie składni z, #pragma GCC diagnostics push #pragma GCC diagnostics ignored "-Wdeprecated-declarations" .. .. Code here .. .. #pragma GCC diagnostic pop ponieważ ta metoda przeniesie Cię z powrotem do ustawień, które zostały ustawione wcześniej. [ Gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html]
Niclas
3
Zmienione zgodnie z sugestiami :)
manicaesar
144

Clang udostępnia przydatną funkcję, która sprawia, że ​​krok „przywracania” w poście @manicaesar jest niezależny od początkowego stanu ostrzeżenia:

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

Cytując instrukcję Clang :

Oprócz wszystkich funkcji dostarczonych przez pragmę GCC, Clang pozwala również na wypychanie i wyświetlanie bieżącego stanu ostrzeżenia. Jest to szczególnie przydatne podczas pisania pliku nagłówkowego, który zostanie skompilowany przez inne osoby, ponieważ nie wiesz, z jakimi flagami ostrzegawczymi one budują.

Andrew Hershberger
źródło
1
Nowsze wersje GCC używają tej samej składni (zamiast GCC zastępuje clang).
Niclas
3
Zawsze jestem zdezorientowany, co to jest LLVM, GCC i Clang. Więc chciałem zostawić notatkę, aby zaoszczędzić czas. Z Xcode 3 użyto GNU Complier Collection (GCC), a następnie Apple wypuściło Xcode 4 z hybrydowym LLVM-GCC. Następnie kompilator maszyny wirtualnej niskiego poziomu (LLVM) przejął kontrolę, zobacz więcej informacji na llvm.org . Od wersji Xcode 7.2.1 domyślnym kompilatorem jest Apple LLVM 7.0. Kompilator LLVM to biblioteka innych "projektów", debuggerów i innych narzędzi, w tym natywny kompilator Clang. Clang to natywny kompilator C / C ++ / Objective-C „LLVM”.
Serge-k
43

Ponieważ zwykle potrzebujemy obsługiwać starsze systemy operacyjne, ale zwróć uwagę na nasze ostrzeżenia, chciałem to zrobić w bardziej uporządkowany sposób. Złożyłem to razem, zainspirowany kodem Mozilli:

#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)

Pozwala to na wykonanie następujących czynności:

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

Działa również z blokami kodu:

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

Ponadto, jeśli zrezygnujesz z obsługi urządzeń starszych niż iOS 7, możesz łatwo przeszukać kod, aby znaleźć przestarzałe zastosowania do naprawienia.

Joe Hughes
źródło
jest to znacznie lepsze długoterminowe rozwiązanie dla większości kodu niż ograniczanie ostrzeżeń o wycofaniu (lub jakichkolwiek innych) na poziomie globalnym / projektu. świetna odpowiedź.
natbro,
1
Dlaczego jest to do { ... } while(0);wymagane?
Ben Leggiero
1
@ BenC.R.Leggiero, ponieważ nie przekazujesz bloku, ale kilka instrukcji między tymi nawiasami. Zasadniczo tłumisz ostrzeżenia dla każdej linii.
Alejandro Iván
1
@ AlejandroIván Wiem, że twoje wyjaśnienie ma dla ciebie sens ... ale dla mnie wygląda na to, że przeformułowałeś pytanie. Czy możesz wyjaśnić, dlaczego do{...}while(0);jest to szczególnie wymagane? Dlaczego nie po prostu {...}? Dlaczego nie if(true){...}? itd.
Ben Leggiero
2
@ BenC.R.Leggiero masz rację. Z jakiegoś powodu źle odczytałem twoje pytanie. Sprawdź zaakceptowaną odpowiedź tutaj: stackoverflow.com/questions/154136/…
Alejandro Iván
29

Możesz również pomijać ostrzeżenia na plik, używając

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

co z kolei sprawia, że ​​jest to trochę lepsza praktyka niż zwykłe tłumienie wszystkich ostrzeżeń raz i razem ... w końcu dowiedziałeś się, po co to robisz.

samiq
źródło
22

Jeśli chcesz wyciszyć ostrzeżenie Implementing deprecated method lub Implementing deprecated class , użyj:

    #pragma clang push diagnostyczny
    #pragma clang diagnostyka ignorowana „-Wdeprecated-implementations”
    // kod
    #pragma clang diagnostyczny pop

Krzysztof
źródło
Kiedy zobaczyłem „-Wdeprecated-declarations”, myślę, że musi istnieć „-Wdeprecated-implementations”. I to naprawdę działa. Dziękuję Ci.
DawnSong
8

W ustawieniach kompilacji znajdź Deprecated Functions.

wprowadź opis obrazu tutaj

SmallChess
źródło
Spowoduje to zamknięcie wszystkich „przestarzałych” ostrzeżeń, jednak tylko niektóre ostrzeżenia muszą zostać pominięte.
DawnSong
2

Jeśli chcesz uzyskać ogólne sprawdzenie pod kątem wszelkiego rodzaju przestarzałych elementów kodu. Proszę używać -Wdeprecated flagę jak poniżej:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma clang diagnostic pop
jarora
źródło
-3

Aby wyłączyć ostrzeżenie z pliku nagłówkowego innej firmy, dodaj następujący wiersz na początku pliku

#pragma clang system_header
Harvestli
źródło