Jak szybko uciszyć ostrzeżenie

98

Mam fragment kodu, który generuje wiele ostrzeżeń (przestarzały interfejs API)

Używając clang * mogłem to zrobić

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    ...
#pragma clang diagnostic pop

Jednak to nie działa szybko.

Jak to zrobić szybko?

Uwaga: nie chcę wyłączać ostrzeżenia globalnie ani nawet całego pliku, ale po prostu wyłączyć określone ostrzeżenie w określonej części mojego kodu źródłowego.

Edycja: Wygląda na to, że moja uwaga nie była wystarczająco jasna: NIE chcę kompilacji warunkowej (która jest proponowaną odpowiedzią na rzekomy duplikat). Chcę tylko wyciszyć ostrzeżenie BEZ korzystania z nowych interfejsów API.

Antzi
źródło
4
To nie jest duplikat. Drugie pytanie nie daje odpowiedzi na ten problem.
Claus Jørgensen,
@ ClausJørgensen, w jaki sposób nie rozwiązuje tego problemu? Nie ma innego sposobu, jak podano w odpowiedziach w połączonym pytaniu. Tylko kompilacja warunkowa lub nowe #availablemakro, w którym programista powinien użyć nowych metod i powrócić do starych, jeśli nowe nie są dostępne.
zrzka
@robertvojta Nie, ponieważ odpowiedzi tak naprawdę nie stwierdzają, że nie ma innego sposobu na uciszenie ostrzeżenia.
Claus Jørgensen
2
To nie jest oszustwo. A co z sytuacją, w której otrzymujesz ostrzeżenie o braku inicjatora?
NSTJ,

Odpowiedzi:

161

Od 2020 r., Xcode 12.0, konsensus jest taki, że nie ma sposobu, aby to osiągnąć.

Zaktualizuję / edytuję tę odpowiedź, jeśli Apple doda tę funkcję.

Umieść to na swojej liście życzeń na WWDC 2021!

Antzi
źródło
22
Cholera, to kłopot. Czasami wymyka się spod kontroli . To co najmniej denerwujące.
Isuru,
2
Chcę milion razy
odrzucać
3
@Isuru W tym momencie byłbym na tyle zirytowany, że po prostu odbudowałem całość. Zgadnij, że ostrzeżenia zadziałały
Sirens
1
@Isuru Większość z nich powinna zostać naprawiona, a nie ignorowana.
kevin
3
Bardzo frustrujące! Dziękujemy za aktualizowanie tej odpowiedzi.
Dan Loewenherz
48

Nie ma ogólnej konstrukcji wyciszania ostrzeżeń o wycofaniu w Swift, ale istnieje obejście, które można zastosować w wielu przypadkach .

Powiedzmy, że masz getLatestImage()w klasie metodę, Fooktóra używa przestarzałych metod / klas.

Użyj tego, @availableco opisał Daniel Thorpe, aby wyciszyć wszystkie ostrzeżenia wewnątrz metody:

@available(iOS, deprecated: 9.0)
func getLatestImage() -> UIImage? {
    ...
}

Teraz chciałbyś wywołać metodę getLatestImage()bez ostrzeżenia o wycofaniu. Możesz to osiągnąć, definiując najpierw protokół i rozszerzenie:

private protocol GetLatestImage {
    func getLatestImage() -> UIImage?
}
extension Foo: GetLatestImage {}

Następnie wywołaj metodę bez ostrzeżenia o wycofaniu (jeśli foojest instancją Foo):

(foo as GetLatestImage).getLatestImage() // no deprecation warning

W rezultacie masz kod Swift, który używa przestarzałego interfejsu API bez żadnych ostrzeżeń o wycofaniu.

Tammo Freese
źródło
Taki mądry. Rodzaj zła? :) Ale tak dobrze. Świetnie nadaje się do przypadków użycia, takich jak pomijanie ostrzeżeń o ciągłym używaniu niektórych aspektów struktury AddressBook, które zostały wycofane, ale które zostały zastąpione, w rzeczywistości nie zapewniają jeszcze wszystkich wymaganych funkcji. Dzięki.
Duncan Babbage
4
jeśli to zadziała, wyślę ci sześciopak twojego ulubionego drinka. Pan ma wybitny umysł, dziękuję.
Jan
@John Dzięki za miłe słowa! To działa, musiałem to wymyślić, ponieważ traktujemy ostrzeżenia jako błędy w naszej bazie kodu, a jedna sekcja nadal używa przestarzałej biblioteki.
Tammo Freese
1
@John, czy wysłałeś mu sześciopak? : P To jest niesamowite. Geniusz. Dzięki.
Baran Emre
Jesteś złym geniuszem.
Krypt
37

W rzeczywistości można wyłączyć te ostrzeżenia, używając @availablew otaczającej strukturze logicznej (tj. Funkcji / typu).

Na przykład załóżmy, że masz kod, który korzysta ze struktury AddressBook, ale tworzysz w systemie iOS 9.

@available(iOS, deprecated: 9.0)
func addressBookStatus() -> ABAuthorizationStatus {
    return ABAddressBookGetAuthorizationStatus()
}

Począwszy od Xcode 7.0.1 zapobiegnie to wyświetlaniu ostrzeżeń wbudowanych.

Daniel Thorpe
źródło
6
Tak, ale zobaczysz to samo ostrzeżenie, gdy zadzwonisz do swojego addressBookStatus()..., które oznaczysz jako przestarzałe.
Valentin Shergin
3
Wskazówka dla profesjonalistów: jeśli chcesz uciszyć to dla całej klasy, po prostu uderz tego szczeniaka ponad swoją deklarację klasową (np. class ViewController: UIViewController)
Syreny
2
@Sirens Wtedy zobaczysz to ostrzeżenie za każdym razem, gdy zadzwonisz do tej klasy ☹️ (przynajmniej z Xcode 8)
Alexander Vasenin
Czy dzięki tej poprawce komuś udało się wyciszyć wszystkie przestarzałe ostrzeżenia? Udało mi się zmniejszyć ich liczbę do jednej , ale nie widzę sposobu na pozbycie się ostatniego. Jakieś sugestie?
Alexander Vasenin
1
Jak więc użyć tego, aby wyciszyć ostrzeżenie „rzutowanie z„ CGFloat.NativeType ”(aka„ Double ”) do niepowiązanego typu„ Float ”zawsze zawodzi”, gdy wykonujęif CGFloat(0).native is Float { … } ? Odpowiedź: Nie używam tego, ponieważ nie odpowiedziałeś na pytanie.
Slipp D. Thompson,
1

Chociaż na razie nie ma sposobu na wyciszenie ostrzeżeń o wycofaniu w Swift, technicznie możesz to zrobić dla określonego symbolu, edytując plik nagłówkowy.

  • Skopiuj przestarzałą nazwę symbolu
  • Wybierz File>Open Quickly
  • Wklej symbol i naciśnij Enter

    Upewnij się, że ikona Swift jest wyłączona w polu Otwórz szybko

  • Wybierz File>Show in Finder

  • W razie potrzeby zmień uprawnienia do plików, aby umożliwić edycję
  • Edytuj przestarzałe makra dla symbolu. Zobacz otaczające interfejsy API w celach informacyjnych. Np. Wymienić:

__OSX_AVAILABLE_BUT_DEPRECATED (__ MAC_10_6, __MAC_10_10, __IPHONE_3_0, __IPHONE_8_0)

z

__OSX_AVAILABLE_STARTING (__ MAC_10_6, __IPHONE_3_0)

Teraz jest jedno rozpraszające ostrzeżenie mniej, z którym nie możesz nic zrobić.

Wiem, jest brudne. Ale jeśli w obecnym SDK nie ma dostępnego zastępczego interfejsu API , powinien być bezpieczny. Gdy pojawi się nowa wersja Xcode, zmiana zostanie nadpisana i ponownie zobaczysz ostrzeżenie. Następnie możesz przetestować nowy pakiet SDK i system operacyjny, aby upewnić się, że wycofany interfejs API jest nadal dostępny i nie został zastąpiony.

Prosimy o komentarz, jeśli możesz wymyślić jakieś wady.

pointum
źródło
Głosowanie za zaradnością, ale pozostawiłoby to w ustach nieprzyjemny smak: P
Matt