Pregunta #ifdef replacement en el lenguaje Swift


En C / C ++ / Objective-C puede definir una macro utilizando los preprocesadores del compilador. Además, puede incluir / excluir algunas partes de código utilizando los preprocesadores del compilador.

#ifdef DEBUG
    // Debug-only code
#endif

¿Hay una solución similar en Swift?


574
2018-06-02 21:06


origen


Respuestas:


Sí, tú puedes hacerlo.

En Swift todavía puede usar las macros del preprocesador "# if / # else / # endif" (aunque más restringido), según Documentos de Apple. Aquí hay un ejemplo:

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

Ahora, debe establecer el símbolo "DEBUG" en otro lugar, sin embargo. Colóquelo en la sección "Compilador Swift - Banderas personalizadas", en la línea "Otras banderas rápidas". Agrega el símbolo DEBUG con el -D DEBUG entrada.

Como de costumbre, puede establecer un valor diferente cuando está en Debug o cuando está en Release.

Lo probé en código real y funciona; sin embargo, no parece ser reconocido en un patio de recreo.

Puedes leer mi publicación original aquí.


NOTA IMPORTANTE:  -DDEBUG=1 no funciona Solamente -D DEBUG trabajos. Parece que el compilador está ignorando una bandera con un valor específico.


858
2018-06-11 00:01



Como se indica en Apple Docs

El compilador Swift no incluye un preprocesador. En su lugar, aprovecha los atributos de tiempo de compilación, las configuraciones de compilación y las características del lenguaje para lograr la misma funcionalidad. Por este motivo, las directivas de preprocesador no se importan en Swift.

Logré lograr lo que quería usando configuraciones de compilación personalizadas:

  1. Vaya a su proyecto / seleccione su objetivo / Configuraciones de compilación / busque Banderas personalizadas
  2. Para su objetivo elegido establezca su indicador personalizado utilizando el prefijo -D (sin espacios en blanco), tanto para la depuración como para el lanzamiento
  3. Haga los pasos anteriores para cada objetivo que tenga

A continuación, le mostramos cómo verificar el objetivo:

#if BANANA
    print("We have a banana")
#elseif MELONA
    print("Melona")
#else
    print("Kiwi")
#endif

enter image description here

Probado usando Swift 2.2


287
2018-04-08 14:57



En muchas situaciones, realmente no necesita condicional Compilacion; solo necesitas condicional comportamiento que puedes encender y apagar Para eso, puedes usar una variable de entorno. Esto tiene la gran ventaja de que en realidad no tiene que volver a compilar.

Puede configurar la variable de entorno y activarla o desactivarla fácilmente en el editor de esquemas:

enter image description here

Puede recuperar la variable de entorno con NSProcessInfo:

    let dic = NSProcessInfo.processInfo().environment
    if dic["TRIPLE"] != nil {
        // ... do secret stuff here ...
    }

Aquí hay un ejemplo de la vida real. Mi aplicación se ejecuta solo en el dispositivo, porque usa la biblioteca de música, que no existe en el simulador. ¿Cómo, entonces, tomar capturas de pantalla en el simulador para dispositivos que no son de mi propiedad? Sin esas capturas de pantalla, no puedo enviarlas a la AppStore.

Necesito datos falsos y un diferente forma de procesarlo. Tengo dos variables de entorno: una que, cuando se enciende, le dice a la aplicación que genere datos falsos a partir de los datos reales mientras se ejecuta en mi dispositivo; el otro que, cuando se enciende, usa los datos falsos (no la biblioteca de música faltante) mientras se ejecuta en el simulador. Activar / desactivar cada uno de esos modos especiales es fácil gracias a las casillas de verificación de variable de entorno en el editor de Scheme. Y la ventaja es que no puedo usarlos accidentalmente en mi compilación de App Store, porque el archivo no tiene variables de entorno.


145
2018-06-21 18:13



Un cambio importante de ifdef reemplazo apareció con Xcode 8. es decir, el uso de Condiciones de compilación activa.

Referirse a Construyendo y Vinculando en Nota de lanzamiento de Xcode 8.

Nueva configuración de compilación

Nueva configuración: SWIFT_ACTIVE_COMPILATION_CONDITIONS

“Active Compilation Conditions” is a new build setting for passing conditional compilation flags to the Swift compiler.

Anteriormente, teníamos que declarar sus banderas de compilación condicionales en OTHER_SWIFT_FLAGS, recordando anteponer "-D" a la configuración. Por ejemplo, para compilar condicionalmente con un valor MYFLAG:

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

El valor para agregar a la configuración -DMYFLAG

Ahora solo tenemos que pasar el valor MYFLAG a la nueva configuración. ¡Hora de mover todos esos valores de compilación condicional!

Consulte el siguiente enlace para obtener más características de Swift Build Settings en Xcode 8: http://www.miqu.me/blog/2016/07/31/xcode-8-new-build-settings-and-analyzer-improvements/


119
2017-09-11 10:57



Xcode 8 y superior

Utilizar Condiciones de compilación activa instalándose Configuraciones de compilación / compilador Swift - Banderas personalizadas.

  • Esta es la nueva configuración de compilación para pasar indicadores de compilación condicional al compilador de Swift.
  • Simple agregar indicadores como este: ALPHA, BETA etc.

Luego compruébalo con condiciones de compilación Me gusta esto:

#if ALPHA
    //
#elseif BETA
    //
#else
    //
#endif

Sugerencia: también puede usar #if !ALPHA etc.


73
2018-01-13 10:26



A partir de Swift 4.1, si todo lo que necesita es simplemente verificar si el código está construido con configuración de depuración o liberación, puede usar las funciones integradas:

  • _isDebugAssertConfiguration() (verdadero cuando la optimización está configurada para -Onone)
  • _isReleaseAssertConfiguration() (verdadero cuando la optimización está configurada para -O) (no disponible en Swift 3+)
  • _isFastAssertConfiguration() (verdadero cuando la optimización está configurada para -Ounchecked)

p.ej.

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

Comparado con las macros del preprocesador,

  • ✓ No necesita definir una costumbre -D DEBUG bandera para usarlo
  • ~ En realidad se define en términos de configuración de optimización, no configuración de compilación de Xcode
  • ✗ Sin documentar, lo que significa que la función se puede eliminar en cualquier actualización (pero debe ser apta para la tienda de aplicaciones, ya que el optimizador las convertirá en constantes)

  • ✗ Usar en if / else siempre generará una advertencia de "No se ejecutará nunca".


73
2017-12-30 15:43



No hay preprocesador Swift. (Por un lado, la sustitución de código arbitrario rompe seguridad de tipo y memoria).

Sin embargo, Swift incluye opciones de configuración de tiempo de compilación, por lo que puede incluir código de forma condicional para ciertas plataformas o estilos de compilación o en respuesta a las marcas que defina con -D compilador args. Sin embargo, a diferencia de C, una sección compilada condicionalmente de su código debe estar sintácticamente completa. Hay una sección sobre esto en Usando Swift con Cocoa y Objective-C.

Por ejemplo:

#if os(iOS)
    let color = UIColor.redColor()
#else
    let color = NSColor.redColor()
#endif

70
2018-06-02 21:17