En C / C ++ / Objective C puede definir una macro utilizando preprocesadores de compilación. Además, puede incluir / excluir algunas partes del código utilizando preprocesadores del compilador.
#ifdef DEBUG
// Debug-only code
#endif
¿Hay una solución similar en Swift?

Respuestas:
Sí, tú puedes hacerlo.
En Swift todavía puede usar las macros de preprocesador "# if / # else / # endif" (aunque más restringido), según los documentos de Apple . Aquí hay un ejemplo:
Ahora, sin embargo, debe establecer el símbolo "DEPURAR" en otro lugar. Configúrelo en la sección "Compilador Swift - Banderas personalizadas", línea "Otras banderas Swift". Agrega el símbolo DEPURAR con la
-D DEBUGentrada.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=1no funciona. Solo-D DEBUGfunciona. Parece que el compilador está ignorando una bandera con un valor específico.fuente
-D DEBUGcomo se indicó anteriormente, también debe definirDEBUG=1enApple LLVM 6.0 - Preprocessing->Preprocessor Macros.-DDEBUGde esta respuesta: stackoverflow.com/a/24112024/747369 .DEBUG=1aPreprocessor Macros, si no se desea utilizar en el código Objective-C.Como se indica en Apple Docs
Me las arreglé para lograr lo que quería usando configuraciones de compilación personalizadas:
Así es como verifica el objetivo:
Probado con Swift 2.2
fuente
-DLOCAL, en mi#if LOCAl #else #endif, cae en la#elsesección. Dupliqué el objetivo originalAppTargety le cambié el nombre aAppTargetLocaly configuré su bandera personalizada.#if LOCALel resultado deseado cuando corro con el simulador y cae#elsedurante las pruebas. Quiero que caiga#if LOCALtambién durante las pruebas.En muchas situaciones, realmente no necesita compilación condicional ; solo necesita un comportamiento condicional que pueda activar y desactivar. Para eso, puede 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:
Puede recuperar la variable de entorno con NSProcessInfo:
Aquí hay un ejemplo de la vida real. Mi aplicación solo se ejecuta 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 tengo? Sin esas capturas de pantalla, no puedo enviarme a la AppStore.
Necesito datos falsos y una forma diferente de procesarlos . Tengo dos variables de entorno: una que, cuando está encendida, le dice a la aplicación que genere datos falsos a partir de datos reales mientras se ejecuta en mi dispositivo; el otro que, cuando se enciende, usa los datos falsos (no la biblioteca de música que falta) 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 las variables de entorno en el editor de esquemas. Y la ventaja es que no puedo usarlos accidentalmente en la compilación de mi tienda de aplicaciones, porque el archivo no tiene variables de entorno.
fuente
Se
ifdefprodujo un cambio importante de reemplazo con Xcode 8. es decir, el uso de condiciones de compilación activa .Consulte Crear y vincular en la nota de versión de Xcode 8 .
Nueva configuración de compilación
Nueva configuración:
SWIFT_ACTIVE_COMPILATION_CONDITIONSAnteriormente, teníamos que declarar sus marcas de compilación condicional en OTHER_SWIFT_FLAGS, recordando anteponer "-D" a la configuración. Por ejemplo, para compilar condicionalmente con un valor MYFLAG:
El valor para agregar a la configuración
-DMYFLAGAhora solo necesitamos pasar el valor MYFLAG a la nueva configuración. ¡Es hora de mover todos esos valores de compilación condicional!
Consulte el siguiente enlace para obtener más funciones de configuración de compilación rápida en Xcode 8: http://www.miqu.me/blog/2016/07/31/xcode-8-new-build-settings-and-analyzer-improvements/
fuente
A partir de Swift 4.1, si todo lo que necesita es verificar si el código está construido con la configuración de depuración o liberación, puede usar las funciones integradas:
_isDebugAssertConfiguration()(verdadero cuando la optimización se establece en-Onone)(no disponible en Swift 3+)_isReleaseAssertConfiguration()(verdadero cuando la optimización se establece en-O)_isFastAssertConfiguration()(verdadero cuando la optimización se establece en-Ounchecked)p.ej
En comparación con las macros de preprocesador,
-D DEBUGbandera personalizada para usarla✗ Sin documentar, lo que significa que la función se puede eliminar en cualquier actualización (pero debe ser segura para AppStore ya que el optimizador las convertirá en constantes)
@testableatributos , el destino es incierto en el futuro Swift.✗ El uso de if / else siempre generará una advertencia de "Nunca se ejecutará".
fuente
if _isDebugAssertConfiguration()será evaluadoif falseen modo de lanzamiento yif truees modo de depuración.Xcode 8 y superior
Utilice la compilación condiciones activas configuración en configuración de generación / Swift compilador - banderas personalizadas .
ALPHA,BETAetc.Luego verifíquelo con condiciones de compilación como esta:
fuente
No hay un preprocesador Swift. (Por un lado, la sustitución de código arbitrario rompe la seguridad de tipo y memoria).
Sin embargo, Swift incluye opciones de configuración de tiempo de compilación, por lo que puede incluir condicionalmente código para ciertas plataformas o estilos de compilación o en respuesta a las banderas que defina con
-Dargumentos del compilador. 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 Uso de Swift con cacao y Objective-C .Por ejemplo:
fuente
INT_CONSTlugar en cualquier lugar dondefloatsea aceptado. Swift no permitiría esto. Además, si pudieras hacerlovar floatVal = INT_CONSTinevitablemente, se descompondría en algún momento más tarde cuando el compilador espera unIntpero lo usas como unFloat(tipo defloatValse infiere comoInt). 10 lanzamientos más tarde y es más limpio para eliminar macros ...Mis dos centavos para Xcode 8:
a) Una marca personalizada que usa el
-Dprefijo funciona bien, pero ...b) Uso más simple:
En Xcode 8 hay una nueva sección: "Condiciones de compilación activa", ya con dos filas, para depurar y liberar.
Simplemente agregue su definición SIN
-D.fuente
-D.isDebug Constant basado en condiciones de compilación activa
Otra solución, quizás más simple, que todavía da como resultado un valor booleano que puede pasar a funciones sin
#ifcondicionar los condicionales en toda su base de código es definirDEBUGcomo uno de los objetivos de compilación de su proyectoActive Compilation Conditionse incluir lo siguiente (lo defino como una constante global):Constante isDebug basada en la configuración de optimización del compilador
Este concepto se basa en la respuesta de kennytm
La principal ventaja cuando se compara con los de kennytm es que esto no depende de métodos privados o indocumentados.
En Swift 4 :
En comparación con las macros del preprocesador y la respuesta de kennytm ,
-D DEBUGbandera personalizada para usarla✓ Documentado , lo que significa que la función seguirá los patrones normales de liberación / desaprobación de API.
✓ El uso de if / else no generará una advertencia de "Nunca se ejecutará".
fuente
La respuesta de Moignans aquí funciona bien. Aquí hay otra paz de información en caso de que ayude,
Puede negar las macros como a continuación,
fuente
En proyectos Swift creados con Xcode Versión 9.4.1, Swift 4.1
funciona de forma predeterminada porque en el preprocesador Macros DEBUG = 1 ya ha sido configurado por Xcode.
Entonces puede usar #if DEBUG "fuera de la caja".
Por cierto, cómo usar los bloques de compilación de condiciones en general está escrito en el libro de Apple The Swift Programming Language 4.1 (la sección Declaraciones de control del compilador) y cómo escribir los indicadores de compilación y qué es la contraparte de las macros C en Swift está escrito en otro libro de Apple Uso de Swift con cacao y Objetivo C (en la sección Directivas de preprocesador)
Espero que en el futuro Apple escriba los contenidos más detallados y los índices de sus libros.
fuente
XCODE 9 Y ARRIBA
fuente
Después de configurar
DEBUG=1laGCC_PREPROCESSOR_DEFINITIONSConfiguración de compilación, prefiero usar una función para realizar estas llamadas:Y luego solo encierre en esta función cualquier bloque que quiera omitir en las compilaciones de depuración:
La ventaja en comparación con:
Es que el compilador verifica la sintaxis de mi código, así que estoy seguro de que su sintaxis es correcta y compila.
fuente
! [En Xcode 8 y superiores, vaya a la configuración de compilación -> busque banderas personalizadas] 1
En codigo
fuente
Fuente
fuente
@inlinabledelantefuncy esta sería la forma más elegante e idiomática para Swift. En las versiones de lanzamiento, tucode()bloque se optimizará y eliminará por completo. Una función similar se utiliza en el propio marco NIO de Apple.Esto se basa en la respuesta de Jon Willis que se basa en la afirmación, que solo se ejecuta en compilaciones de depuración:
Mi caso de uso es para registrar declaraciones impresas. Aquí hay un punto de referencia para la versión de lanzamiento en iPhone X:
huellas dactilares:
Parece que Swift 4 elimina por completo la llamada a la función.
fuente