2011-12-18 11 views
34

A menudo vi "afirmar" en el código de iOS, lo googleé y llegué a saber que es verdadero o falso.¿Cómo saber si NSAssert está deshabilitado en versiones de lanzamiento?

Quiero saber si esto se desactivará automáticamente en el modo de lanzamiento?

+2

Es, francamente, un diseño loco que afirma que no está desactivado en versiones de lanzamiento por defecto. Vuela frente a cualquier otro compilador de C que conozco. –

+0

@SevaAlekseyev De acuerdo, recibimos un shock cuando las Afirmaciones aún aparecían en Release. Completamente no convencional. Nuestra filosofía es 'fallar rápido en el desarrollo, morir duro en la producción'. –

Respuesta

38

Utilice NSAssert() y sus acompañantes.

en el proyecto define NS_BLOCK_ASSERTIONS para la configuración de su versión.

Xcode 4 tremplates desactivar NSAsserts en la configuración de lanzamiento. Agrega

-DNS_BLOCK_ASSERTIONS=1 

a "Otros indicadores C" para "Liberar".

De la documentación:

afirmaciones se desactiva si se define el preprocesador macro NS_BLOCK_ASSERTIONS.

La macro NSAssert evalúa la condición y sirve como interfaz del manejador de aserciones.

Cada subproceso tiene su propio controlador de aserción, que es un objeto de la clase NSAssertionHandler. Cuando se invoca, un controlador de aserciones imprime un mensaje de error que incluye el método y los nombres de clase (o el nombre de la función). Luego se lanza una excepción NSInternalInconsistencyException. Si la condición se evalúa como NO, la macro invoca handleFailureInMethod:object:file:lineNumber:description: en el manejador de aserción para el subproceso actual, pasando desc como la cadena de descripción.

Esta macro solo se debe utilizar con los métodos de Objective-C.

4

Las afirmaciones se compilan condicionalmente fuera de su código cuando se define NDEBUG. Si define NDEBUG=1 en la sección de configuración de compilación correspondiente, desactivará las afirmaciones en su código independientemente del modo de liberación o depuración.

24

voy a dar aquí un meta-respuesta:

Tanto @CocoaFu y @dasblinkenlight son correctas. NS_BLOCK_ASSERTIONS apaga NSAssert() y NDEBUG apaga assert(). Necesitará ambos si usa ambos.

+0

Lectura de iOS 5 Programación por @Rob: Obténgalo, léalo, programe mejor en iOS 5. – zaph

+0

Desafortunadamente, en su resumen de las dos palabras, deletreó una erróneamente. – Ant

+1

Observado y reparado. NSDEBUG-> NDEBUG –

7

Como dijo Zaph, -DNS_BLOCK_ASSERTIONS=1 está listo para su lanzamiento. Sin embargo, si quieres verificar esto.

Observe primero en los documentos que NSAssert está deshabilitado por la macro NS_BLOCK_ASSERTIONS. A continuación, añadir esto a la acumulación y la guardan cumple bien:

#ifdef NS_BLOCK_ASSERTIONS 
#error Error - NS_BLOCK_ASSERTIONS is defined 
#endif 

a continuación, cambiar el esquema de liberar (cmd - cambio - <)

enter image description here

luego observar que la generación falla. Por lo tanto, se define NS_BLOCK_ASSERTIONS, lo que significa que NSAssert s están deshabilitados.

0

Ahora, a partir de Xcode 6, la configuración es ENABLE_NS_ASSERTIONS, que se establece en 1 para configuraciones de depuración y 0 para Versión, de forma predeterminada.

Puede optar en él para la liberación se basa en la línea de comandos al pasar el argumento ENABLE_NS_ASSERTIONS=1, lo que estoy haciendo para ejecutar pruebas unitarias que comprueban las condiciones de aserción, pero por lo demás debe correr con la bandera DEBUG fuera.

26

Actualización: Verificado esto también funciona en Xcode 8.

En Xcode 7, entrar en la configuración del proyecto de construcción y la búsqueda de "aserción" en la barra de búsqueda. Esto muestra la sección "Apple LLVM 7.0 - Preprocesamiento" sección. Hay una configuración llamada "Habilitar afirmaciones de la Fundación".

He habilitado/inhabilitado correctamente NSAssert desde allí.

enter image description here

+2

que agrega un indicador 'ENABLE_NS_ASSERTIONS = NO; 'al archivo' AppName.xcodeproj/project.pbxproj' de la aplicación – computingfreak

0

Aquí es lo que hago en la parte superior de mi main():

#if defined(NDEBUG) 
{ 
    // The assertion code below should be compiled out of existence in a release 
    // build. Log an error and abort the program if it is not. 
    bool ok = true; 
    NSCAssert(ok = false, @"NS assertions should be disabled but are not"); 
    if (!ok) 
    { 
    NSLog(@"Detected release build but NS_BLOCK_ASSERTIONS is not defined"); 
    return -1; 
    } 
} 
#endif 

Nota que desde main() es una función C y no una función de Objective-C, NSCAssert se utiliza anteriormente en lugar de NSAssert . (NSAssert espera que self sea válido.)

Cuestiones relacionadas