877 Stimmen

#ifdef Ersatz in der Swift-Sprache

In C/C++/Objective C können Sie mit Compiler-Präprozessoren ein Makro definieren. Außerdem können Sie mit Compiler-Präprozessoren einige Teile des Codes ein- oder ausschließen.

#ifdef DEBUG
    // Nur im Debug-Modus
#endif

Gibt es eine ähnliche Lösung in Swift?

1215voto

Jean Le Moignan Punkte 21842

Ja, du kannst es machen.

In Swift kannst du immer noch die Präprozessor-Makros "#if/#else/#endif" verwenden (obwohl sie strenger sind), wie in den Apple-Dokumenten beschrieben. Hier ist ein Beispiel:

#if DEBUG
    let a = 2
#else
    let a = 3
#endif

Jetzt musst du das "DEBUG"-Symbol anderswo setzen. Setze es im Abschnitt "Swift Compiler - Custom Flags", Zeile "Other Swift Flags". Du fügst das DEBUG-Symbol mit dem -D DEBUG Eintrag hinzu.

Wie üblich kannst du einen anderen Wert festlegen, wenn im Debug- oder Release-Modus.

Ich habe es in echtem Code getestet und es funktioniert; es scheint jedoch nicht in einem Playground erkannt zu werden.

Meinen Originalbeitrag kannst du hier lesen.


WICHTIGER HINWEIS: -DDEBUG=1 funktioniert nicht. Nur -D DEBUG funktioniert. Es scheint, dass der Compiler eine Flagge mit einem spezifischen Wert ignoriert.

413voto

Andrej Punkte 6928

Wie in Apple Docs angegeben

Der Swift-Compiler enthält keinen Preprozessor. Stattdessen nutzt er Kompilierzeit-Attribute, Build-Konfigurationen und Sprachfunktionen, um die gleiche Funktionalität zu erreichen. Aus diesem Grund werden Präprozessor-Anweisungen in Swift nicht importiert.

Es ist mir gelungen, zu erreichen, was ich wollte, indem ich benutzerdefinierte Build-Konfigurationen verwendet habe:

  1. Gehen Sie zu Ihrem Projekt / wählen Sie Ihr Ziel / Build-Einstellungen / suchen Sie nach benutzerdefinierten Flags
  2. Für Ihr ausgewähltes Ziel setzen Sie Ihr benutzerdefiniertes Flag mit dem Präfix -D (ohne Leerzeichen), sowohl für Debug als auch für Release
  3. Führen Sie die oben genannten Schritte für jedes Ziel durch, das Sie haben

So prüfen Sie das Ziel:

#if BANANA
    print("Wir haben eine Banane")
#elseif MELONA
    print("Melona")
#else
    print("Kiwi")
#endif

Bildbeschreibung hier eingeben

Getestet mit Swift 2.2

187voto

DShah Punkte 9624

Ein großer Wechsel der ifdef-Ersetzung kam mit Xcode 8 auf. d.h. Verwendung von Aktiven Kompilierbedingungen.

Beziehen Sie sich auf Erstellen und Verknüpfen in Xcode 8 Versionshinweis.

Neue Build-Einstellungen

Neue Einstellung: SWIFT_ACTIVE_COMPILATION_CONDITIONS

„Aktive Kompilierbedingungen“ ist eine neue Build-Einstellung zur Übermittlung von bedingten Kompilierungsflaggen an den Swift-Compiler.

Zuvor mussten wir Ihre bedingten Kompilierungsflaggen unter OTHER_SWIFT_FLAGS deklarieren, wobei wir daran denken mussten, „-D“ vor die Einstellung zu setzen. Zum Beispiel, um bedingt mit einem MYFLAG-Wert zu kompilieren:

#if MYFLAG1
    // Zeug 1
#elseif MYFLAG2
    // Zeug 2
else
    // Zeug 3
#endif

Der Wert, der zur Einstellung hinzugefügt werden soll, lautet -DMYFLAG

Jetzt müssen wir nur noch den Wert MYFLAG an die neue Einstellung übergeben. Zeit, all diese bedingten Kompilierungswerte zu verschieben!

Bitte beziehen Sie sich auf den folgenden Link für weitere Swift Build-Einstellungen in Xcode 8: http://www.miqu.me/blog/2016/07/31/xcode-8-new-build-settings-and-analyzer-improvements/

186voto

matt Punkte 481428

In vielen Situationen benötigen Sie nicht unbedingt eine bedingte Kompilierung; Sie benötigen einfach bedingtes Verhalten, das Sie ein- und ausschalten können. Dafür können Sie eine Umgebungsvariable verwenden. Der große Vorteil dabei ist, dass Sie tatsächlich nicht neu kompilieren müssen.

Sie können die Umgebungsvariable im Scheme-Editor festlegen und ganz einfach ein- oder ausschalten:

Bildbeschreibung hier eingeben

Sie können die Umgebungsvariable mit NSProcessInfo abrufen:

    let dic = NSProcessInfo.processInfo().environment
    if dic["TRIPLE"] != nil {
        // ... hier geheime Dinge tun ...
    }

Hier ist ein Beispiel aus dem echten Leben. Meine App läuft nur auf dem Gerät, weil sie die Musikbibliothek verwendet, die auf dem Simulator nicht existiert. Wie kann ich also Screenshots auf dem Simulator für Geräte machen, die ich nicht besitze? Ohne diese Screenshots kann ich nicht im AppStore veröffentlichen.

Ich benötige gefälschte Daten und eine andere Verarbeitungsmethode. Ich habe zwei Umgebungsvariablen: Eine davon schaltet während des Betriebs auf meinem Gerät um, um die gefälschten Daten aus den echten Daten zu generieren; die andere schaltet um, um die gefälschten Daten (nicht die fehlende Musikbibliothek) auf dem Simulator zu verwenden. Das Ein- und Ausschalten dieser speziellen Modi ist dank der Umgebungsvariablen-Kontrollkästchen im Scheme-Editor einfach. Und der Bonus ist, dass ich sie nicht versehentlich in meiner App Store-Build verwenden kann, weil beim Archivieren keine Umgebungsvariablen vorhanden sind.

99voto

kennytm Punkte 488916

Ab Swift 4.1, wenn Sie nur überprüfen müssen, ob der Code mit der Debug- oder Release-Konfiguration erstellt wurde, können Sie die integrierten Funktionen verwenden:

  • _isDebugAssertConfiguration() (true, wenn die Optimierung auf -Onone gesetzt ist)
  • _isReleaseAssertConfiguration() (true, wenn die Optimierung auf -O gesetzt ist) (nicht verfügbar ab Swift 3+)
  • _isFastAssertConfiguration() (true, wenn die Optimierung auf -Ounchecked gesetzt ist)

z. B.

func obtain() -> AbstractThing {
    if _isDebugAssertConfiguration() {
        return DecoratedThingWithDebugInformation(Thing())
    } else {
        return Thing()
    }
}

Im Vergleich zu Präprozessor-Makros:

  • Sie müssen keine benutzerdefinierte -D DEBUG Flagge definieren, um sie zu verwenden
  • ~ Es ist tatsächlich in Bezug auf Optimierungseinstellungen definiert, nicht auf die Xcode-Build-Konfiguration
  • Unerwähnt, was bedeutet, dass die Funktion in jedem Update entfernt werden kann (aber sie sollte AppStore-sicher sein, da der Optimierer diese in Konstanten umwandeln wird)

  • Verwendung in if/else wird immer eine "Wird nie ausgeführt" Warnung generieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X