ios - ¿Debo desactivar NSLog antes de lanzar la aplicación?
iphone (12)
Al lanzar una aplicación para iPhone, si deshabilito NSLog();
funcionará mejor?
Actualización para Xcode 5 y iOS 7
Nota: para una solución Xcode 7 / Swift 2.1 para eliminar instrucciones print () en una compilación de lanzamiento, encuentre mi respuesta here .
Sí, debes eliminar cualquier declaración de NSLog en tu código de lanzamiento, ya que solo ralentiza tu código y no sirve para nada en una versión de lanzamiento. Afortunadamente, en Xcode 5 (iOS 7), es increíblemente simple eliminar todas las declaraciones de NSLog ''automáticamente'' en versiones de lanzamiento. Entonces por qué no hacerlo.
Primero los 3 pasos a seguir, luego algunas explicaciones
1) en su proyecto de Xcode, busque el archivo ''yourProjectName-prefix.pch'' (normalmente lo encontrará debajo del grupo ''archivos de apoyo'', donde se encuentra su archivo main.m
2) agregue estas 3 líneas al final del archivo ''.pch'':
#ifndef DEBUG
#define NSLog(...);
#endif
3) prueba la diferencia entre tu versión de ''depuración'' y ''versión''. Una forma de hacerlo es mediante ''editar esquema'' -> ''ejecutar nombre de la aplicación'' -> debajo de la pestaña ''info'' seleccionar usando el cuadro desplegable entre depurar y liberar. ¡En la versión de lanzamiento no verá ninguna salida NSLog en la consola de depuración!
¿Como funciona todo esto?
En primer lugar, uno debe saber que un preprocesador es relativamente "tonto", y solo actúa como un "sustituto de texto" antes de que se llame al compilador. Reemplaza todo lo que "define" por lo que sigue a la declaración #define
.
#define NSLog(...);
El (...)
significa ''cualquier cosa'' entre los corchetes (). Mente también el ;
al final. Esto no es estrictamente necesario ya que el compilador optimizará esto, pero me gustaría ponerlo allí, ya que es más ''correcto''. Después de nuestro #define
no hay ''nada'', por lo que el preprocesador lo reemplazará con ''nada'', por lo que simplemente descartará la línea completa, comenzando en NSLog...
hasta e incluyendo el ;
.
las declaraciones de definición se pueden hacer condicional usando #ifdef
(si está definido) o #ifndef
(si no está definido)
aquí escribimos #ifndef DEBUG
, que significa ''si el símbolo DEPURACIÓN no está definido''. El #ifdef
o #ifndef
deben estar ''cerrados'' con #endif
Xcode 5 define de forma predeterminada el símbolo ''DEPURAR'' para nosotros cuando el modo de compilación es ''DEPURAR''. En ''lanzamiento'' esto no está definido. puede verificar esto en la configuración de su proyecto, pestaña ''Configuración de compilación'' -> desplácese hacia abajo a la sección ''Apple LLVM 5.0 - Preprocesamiento'' -> macros de preprocesador. ¡Verás que el símbolo ''DEPURACIÓN'' no está definido para versiones de lanzamiento!
finalmente, el archivo .pch es creado por Xcode automáticamente, y se incluye automáticamente en cada archivo fuente durante el tiempo de compilación. Por lo tanto, es como si hubieras puesto toda la cosa #define
en cada uno de tus archivos fuente.
Además de todas las personas que sabiamente comentaron que no llamar a NSLog()
en absoluto en la producción se ejecuta un poco más rápido, NSLog()
que:
Todas las cadenas de salida de NSLog()
son visibles para cualquiera que descargue su aplicación de la tienda y la ejecute con el dispositivo conectado a un mac que ejecuta Xcode (a través de la ventana Organizador).
Dependiendo de la información que inicie sesión (y especialmente si su aplicación contacta con un servidor, realiza la autenticación, etc.), esto puede ser un problema grave de seguridad .
Casi todas las respuestas anteriores sugestionan una solución pero no explican el problema. Hice una búsqueda en google y encontré el motivo. Aquí está mi respuesta:
Sí, si comenta NSLog en su versión de lanzamiento, el rendimiento será mejor. Porque NSLog es bastante lento. ¿Por qué? NSLog hará dos cosas: 1) escribir mensajes de registro en Apple System Logging (ASL); 2) si la aplicación se ejecuta en xcode, también escribe en stderr.
El problema principal está en el primero. Para lograr seguridad de subprocesos, cada vez que se llama a NSLog, abre una conexión a la facilidad de ASL , envía mensajes y cierra la conexión. La operación de conexión es muy costosa. Otra razón es que NSLog dedica algo de tiempo para registrar la marca de tiempo.
Referencia de here
Mi favorito personal es usar una macro variable.
#ifdef NDEBUG
#define NSLog(...) /* suppress NSLog when in release mode */
#endif
NSLog es lento y no debe usarse para versiones de lanzamiento. Una simple macro como la de abajo lo desactivará junto con las afirmaciones que pueda tener, que también deberían deshabilitarse. En el caso menos común en el que desea instalar NSLog en una compilación de lanzamiento, simplemente llámelo directamente. No olvides agregar "-DNDEBUG" a tus configuraciones de compilación "other c flags".
#ifdef NDEBUG
#define MYLog(f, ...)
#else
#define MYLog(f, ...) NSLog(f, ## __VA_ARGS__)
#endif
Sí, debes deshabilitarlo. Especialmente si estás tratando de maximizar la velocidad de tu código. NSLogging cosas a la izquierda y a la derecha contamina el registro del sistema que otros desarrolladores pueden estar tratando de excavar y puede tener un gran impacto en el código de velocidad crítica (bucles internos, etc.) accidentalmente dejé algunos mensajes de registro en una función recursiva una vez tiene que lanzar una actualización con un "aumento del 30% de velocidad" Unas pocas semanas después... ;-)
Todas las buenas respuestas, sin embargo, aquí hay otro pequeño truco que puede considerar usar, principalmente en las fases de desarrollo / prueba de su aplicación.
También podría ser útil para el código de liberación de la aplicación, si solo quiere cambiar su código de depuración, y no mensajes que puedan indicar problemas fuera del control directo de su código.
El truco:
Puede desactivar el archivo NSLog por .M simplemente incluyendo la siguiente línea en la parte superior del archivo .m :
#define NSLog(...)
( NOTA: NO coloque el archivo .h, ¡solo el archivo .m! )
Esto simplemente hace que el compilador evalúe NSLog()
al expandir su macro de preprocesador. La macro no hace más que despojar a los argumentos.
si quieres volver a encenderlo, siempre puedes usar
#undef NSLog
Por ejemplo, podría evitar llamadas a NSLog en torno a un grupo particular de métodos haciendo algo como
#define NSLog(...)
-(void) myProblematicMethodThatSometimesNeedsDebugging {
...
}
#undef NSLog
Una forma de hacerlo es entrar en la configuración de compilación y en la configuración de depuración agregar un valor al valor de "Macros de preprocesador" como:
DEBUG_MODE=1
Asegúrese de hacer esto solo para la configuración de depuración y no para versiones Beta o Release. Luego, en un archivo de encabezado común puede hacer algo como:
#ifdef DEBUG_MODE
#define DLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DLog( s, ... )
#endif
Ahora, en lugar de NSLog
usa DLog
todas partes. Al probar y depurar, obtendrá mensajes de depuración. Cuando esté listo para lanzar una versión beta o final, todas esas líneas DLog
se DLog
automáticamente y no se emite nada. De esta forma, no es necesario configurar manualmente las variables ni comentar los NSLogs
. Escoger tu objetivo de compilación lo resuelve.
en el archivo pch escribe esto antes de #endif
#define NSLog() //
que tal esto?
#ifndef DEBUG_MODE
fclose(stderr); // the simplest way to disable output from NSLog
#endif
Dentro de la configuración predeterminada actual del proyecto en Xcode, la macro NS_BLOCK_ASSERTIONS
se establecerá en 1 en la versión de lanzamiento y DEBUG=1
en la versión de depuración.
Entonces, prefiero el siguiente método.
// NS_BLOCK_ASSERTIONS is defined by default, as shown in the screenshot above.
// Or, you can define yourself Flags in the `Other C Flags` -> `Release`.
#ifndef NS_BLOCK_ASSERTIONS
#define _DEBUG
#endif
#ifdef _DEBUG
// for debug mode
#define DLog(fmt,...) NSLog(@"%s " fmt, __FUNCTION, ##__VA_ARGS__)
... /// something extra
#else
// for release mode
#define DLog(fmt,...) /* throw it away */
... /// something extra
#endif
var showDebugLogs = false;
func DLog(format: String, args: CVarArgType...) {
if showDebugLogs{
println(String(format: format, arguments: args))
}
}
Esto también aceptará los argumentos adicionales. Solo el valor del parámetro showDebugLogs es verdadero o falso, según su necesidad.