2011-06-03 13 views
7

pensé NSAssert no podían utilizar printf especificadores, pero esto:¿Por qué NSAssert1, etc. en lugar de NSAssert?

NSAssert(0, @"%@%@", @"foo", @"bar"); 

funciona igual como era de esperar:

*** Assertion failure in -[MyClass myMethod], <Path>/MyClass.m:84 
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', 
    reason: 'foobar' 

Entonces, ¿cuál es el punto de utilizar NSAssert1, NSAssert2, etc. cuando NSAssert ¿trabajos?

Esto con Xcode 4.0 y iOS 4.3 SDK, si eso importa. (Si no lo hace, actualizaré las etiquetas.)

Respuesta

17

Las versiones actuales de NSAssert() usan macros variadic preprocesador, es decir, __VA_ARGS__. Desde macros variadic son una característica C99, mi suposición es que las versiones anteriores del SDK no permitieron argumentos variables en NSAssert(), de ahí la necesidad de NSAssert1(), NSAssert2(), etc.

Si intenta compilar

NSAssert(0, @"%@%@", @"foo", @"bar"); 

usando -std=c89 o -ansi (ISO C90, una versión anterior de C que no admite macros variadic), se obtiene un error de compilación:

error: too many arguments provided to function-like macro invocation 
    NSAssert(0, @"%@%@", @"foo", @"bar"); 

Para que el bacalao e para compilar con -std=c89 o -ansi, es necesario utilizar NSAssert2():

NSAssert2(0, @"%@%@", @"foo", @"bar"); 
0

excelente respuesta por Bavarious.

Solo le agrego mi bit. Para las personas que enfrentan el problema Too many arguments provided to function-like macro invocation. Preste atención a la parte mencionada como -std=c89 por @Bavarious.

Así es como me deshice del problema.

  1. Ir a la configuración de creación -> Apple LLVM 6.1
  2. Búsqueda dialecto lenguaje C
  3. Cambiar para -std=c99
Cuestiones relacionadas