Wie man eine Warnung schnell zum Schweigen bringt


98

Ich habe einen Code, der viele Warnungen generiert (veraltete API)

Mit clang * könnte ich machen

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

Dies funktioniert jedoch nicht schnell.

Wie geht das schnell?

Hinweis: Ich möchte die Warnung weder global noch dateiweit deaktivieren, sondern nur eine bestimmte Warnung in einem bestimmten Teil meines Quellcodes deaktivieren.

Bearbeiten: Ich sehe aus, als ob meine Notiz nicht klar genug war: Ich möchte KEINE bedingte Kompilierung (was die vorgeschlagene Antwort des vermeintlichen Duplikats ist). Ich möchte nur eine Warnung zum Schweigen bringen, OHNE die neuen APIs zu verwenden.



4
Dies ist kein Duplikat. Die andere Frage beantwortet dieses Problem nicht.
Claus Jørgensen

@ ClausJørgensen Wie kann dieses Problem nicht gelöst werden? Es gibt keinen anderen Weg, wie in den Antworten in der verknüpften Frage angegeben. Nur bedingte Kompilierung oder neues #availableMakro, bei dem Entwickler neue Methoden verwenden und auf die alten zurückgreifen sollten, wenn neue nicht verfügbar sind.
Zrzka

@robertvojta Nein, da die Antworten tatsächlich nicht besagen, dass es keine anderen Möglichkeiten gibt, eine Warnung zum Schweigen zu bringen.
Claus Jørgensen

2
Das ist kein Betrug. Was ist mit einer Situation, in der Sie gewarnt werden, weil Sie einen Initialisierer verpasst haben?
NSTJ

Antworten:


156

Ab 2020, Xcode 12.0, besteht Konsens darüber, dass es keine Möglichkeit gibt, dies zu erreichen.

Ich werde diese Antwort aktualisieren / bearbeiten, wenn Apple die Funktion hinzufügt.

Setzen Sie es in Ihre Wunschliste für WWDC 2021!


20
Verdammt, das ist ein Mist. Es wird manchmal außer Kontrolle geraten . Es ist gelinde gesagt ärgerlich.
Isuru

2
Ich möchte diese Antwort millionenfach
ablehnen

3
@Isuru An diesem Punkt würde ich genug irritiert sein, um einfach das Ganze wieder aufzubauen. Vermutlich haben die Warnungen funktioniert
Sirenen

1
@Isuru Die meisten davon sollten behoben und nicht ignoriert werden.
Kevin

3
So frustrierend! Vielen Dank, dass Sie diese Antwort auf dem neuesten Stand halten.
Dan Loewenherz

48

Es gibt kein allgemeines Konstrukt zum Schweigen von Verfallswarnungen in Swift, aber es gibt eine Problemumgehung, die in vielen Fällen angewendet werden kann .

Angenommen, Sie haben eine Methode getLatestImage()für eine Klasse, Foodie veraltete Methoden / Klassen verwendet.

Verwenden Sie diese Option @availablewie von Daniel Thorpe beschrieben, um alle Warnungen innerhalb der Methode zum Schweigen zu bringen :

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

Jetzt möchten Sie die Methode ohne eine Warnung zur Ablehnung aufrufengetLatestImage() . Sie können dies erreichen, indem Sie zuerst ein Protokoll und eine Erweiterung definieren:

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

Rufen Sie dann die Methode ohne Verfallswarnung auf (wenn fooes sich um eine Instanz von handelt Foo):

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

Das Ergebnis ist, dass Sie über Swift-Code verfügen, der eine veraltete API ohne veraltete Warnungen verwendet.


So klug. Irgendwie böse? :) Aber so gut. Hervorragend geeignet für Anwendungsfälle wie das Unterdrücken von Warnungen bei fortlaufender Verwendung einiger Aspekte des AddressBook-Frameworks, die veraltet sind, deren Ersatz jedoch noch nicht alle erforderlichen Funktionen bietet. Vielen Dank.
Duncan Babbage

4
Wenn dies funktioniert, schicke ich Ihnen ein Sixpack Ihres Lieblingsgetränks. Sie haben einen hervorragenden Verstand, Sir, danke.
John

@ John Danke für die freundlichen Worte! Es funktioniert, ich musste es mir einfallen lassen, da wir Warnungen als Fehler in unserer Codebasis behandeln, und es gibt einen Abschnitt, in dem noch eine veraltete Bibliothek verwendet wird.
Tammo Freese

1
@ John hast du ihm das Sixpack geschickt? : P Das ist großartig. Genius. Vielen Dank.
Baran Emre

Du bist ein böses Genie.
Krypt

36

Eigentlich Sie können diese Warnungen unterdrücken , indem Sie @availablein der umschließenden logische Struktur (dh Funktion / Typ).

Angenommen, Sie haben Code, der das AddressBook-Framework verwendet, aber Sie bauen auf iOS 9.

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

Ab Xcode 7.0.1 wird verhindert, dass Inline-Warnungen angezeigt werden.


6
Ja, aber Sie werden dieselbe Warnung sehen, wenn Sie Ihre addressBookStatus()... anrufen , die Sie als veraltet markieren.
Valentin Shergin

3
Pro - Tipp: wenn Sie es für eine ganze Klasse zum Schweigen bringen wollen Slam nur diese Welpen über die Klassenanweisung (ex: bis class ViewController: UIViewController)
Sirens

2
@ Sirens Dann sehen Sie diese Warnung jedes Mal, wenn Sie diese Klasse anrufen ☹️ (zumindest mit Xcode 8)
Alexander Vasenin

Hat es jemand geschafft, alle veralteten Warnungen mit diesem Fix zum Schweigen zu bringen ? Ich konnte ihre Anzahl auf nur eine reduzieren , aber ich sehe keinen Weg, die letzte loszuwerden. Irgendwelche Vorschläge?
Alexander Vasenin

1
Wie kann man damit die Warnung "Die Umwandlung von" CGFloat.NativeType "(auch bekannt als" Double ") in den nicht verwandten Typ" Float "schlägt immer fehlif CGFloat(0).native is Float { … } ? " Zum Schweigen bringen, wenn ich eine mache ? Antwort: Ich benutze das nicht, weil Sie die Frage nicht beantwortet haben.
Slipp D. Thompson

1

Während es in Swift derzeit keine Möglichkeit gibt, Verfallswarnungen auszuschalten, können Sie dies technisch für ein bestimmtes Symbol tun, indem Sie die Header-Datei bearbeiten.

  • Kopieren Sie den veralteten Symbolnamen
  • Wählen Sie File>Open Quickly
  • Fügen Sie das Symbol ein und drücken Sie Enter

    Stellen Sie sicher, dass das Swift-Symbol im Feld Schnell öffnen deaktiviert ist

  • Wählen Sie File>Show in Finder

  • Ändern Sie die Dateiberechtigungen, um sie gegebenenfalls bearbeiten zu können
  • Bearbeiten Sie die Verfallsmakros für das Symbol. Weitere Informationen finden Sie in den umgebenden APIs. ZB ersetzen:

__OSX_AVAILABLE_BUT_DEPRECATED (__ MAC_10_6, __MAC_10_10, __IPHONE_3_0, __IPHONE_8_0)

mit

__OSX_AVAILABLE_STARTING (__ MAC_10_6, __IPHONE_3_0)

Jetzt gibt es eine weniger ablenkende Warnung, gegen die Sie nichts tun können.

Ich weiß, es ist schmutzig. Wenn im aktuellen SDK jedoch keine Ersatz-API verfügbar ist , sollte diese sicher sein. Sobald eine neue Version von Xcode herauskommt, wird die Änderung überschrieben und Sie sehen die Warnung erneut. Anschließend können Sie das neue SDK und Betriebssystem testen, um sicherzustellen, dass die veraltete API weiterhin verfügbar ist und keinen Ersatz erhalten hat.

Bitte kommentieren Sie, ob Sie Nachteile haben können.


Upvoting für den Einfallsreichtum, aber es würde einen schmutzigen Geschmack in meinem Mund hinterlassen: P
Matt
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.