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 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. Solo-D DEBUG
funciona. Parece que el compilador está ignorando una bandera con un valor específico.fuente
-D DEBUG
como se indicó anteriormente, también debe definirDEBUG=1
enApple LLVM 6.0 - Preprocessing
->Preprocessor Macros
.-DDEBUG
de esta respuesta: stackoverflow.com/a/24112024/747369 .DEBUG=1
aPreprocessor 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#else
sección. Dupliqué el objetivo originalAppTarget
y le cambié el nombre aAppTargetLocal
y configuré su bandera personalizada.#if LOCAL
el resultado deseado cuando corro con el simulador y cae#else
durante las pruebas. Quiero que caiga#if LOCAL
tambié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
ifdef
produjo 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_CONDITIONS
Anteriormente, 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
-DMYFLAG
Ahora 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 DEBUG
bandera 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)
@testable
atributos , 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 false
en modo de lanzamiento yif true
es 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
,BETA
etc.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
-D
argumentos 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_CONST
lugar en cualquier lugar dondefloat
sea aceptado. Swift no permitiría esto. Además, si pudieras hacerlovar floatVal = INT_CONST
inevitablemente, se descompondría en algún momento más tarde cuando el compilador espera unInt
pero lo usas como unFloat
(tipo defloatVal
se 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
-D
prefijo 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
#if
condicionar los condicionales en toda su base de código es definirDEBUG
como uno de los objetivos de compilación de su proyectoActive Compilation Conditions
e 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 DEBUG
bandera 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=1
laGCC_PREPROCESSOR_DEFINITIONS
Configuració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
@inlinable
delantefunc
y 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