2009-03-05 19 views
135

Pregunta simple realmente; ¿Hay alguna diferencia entre estos valores (y hay una diferencia entre BOOL y bool)? Un compañero de trabajo mencionó que evalúan diferentes cosas en Objective-C, pero cuando miré los typedefs en sus respectivos archivos .h, YES/TRUE/true se definieron todos como 1 y NO/FALSE/false se definieron todos como 0. Hay realmente alguna diferencia?¿Hay una diferencia entre SÍ/NO, VERDADERO/FALSO y verdadero/falso en objetivo-c?

+4

Desde un punto de vista práctico, no hay diferencia. Probablemente puedas hacer varios trucos para demostrar la diferencia, pero generalmente te estarás desviando hacia un territorio de "comportamiento indefinido". –

Respuesta

70

No hay diferencia práctica proporcionan se utilizan como variables BOOL booleanos. C procesa expresiones booleanas en función de si se evalúan como 0 o no 0. Por lo tanto:

if(someVar) { ... } 
if(!someVar) { ... } 

significa lo mismo que

if(someVar!=0) { ... } 
if(someVar==0) { ... } 

razón por la cual se puede evaluar cualquier tipo primitivo o expresión como una prueba booleana (incluidos, por ejemplo, punteros). Tenga en cuenta que debe hacer lo primero, no lo último.

Tenga en cuenta que no es una diferencia si asigna valores obtusos a una llamada BOOL variable y prueba para valores específicos, por lo que siempre se utilicen como booleanos y sólo les asigna valores de sus #define.

Importante: nunca pruebe los booleanos usando una comparación de caracteres; no solo es riesgoso porque a someVar se le puede asignar un valor distinto de cero que no es SÍ, pero en mi opinión lo más importante es que no expresa la intención correctamente:

if(someVar==YES) { ... } // don't do this! 
if(someVar==NO) { ... } // don't do this either! 

en otras palabras, usar construcciones, ya que están destinados y documentados para ser utilizado y se le ahorrarse un mundo de dolor en C.

-7

No, SI/NO es una manera diferente para referirse a TRUE/FALSE (1/0)

+3

-1 por no decir por qué – Supuhstar

+3

-1 por no especificar – vilanovi

1

Creo que añaden SÍ/NO para ser más se explica por sí mismo en muchos casos. Por ejemplo:

[button setHidden:YES]; 

suena mejor que

[button setHidden:TRUE]; 
+1

No estoy de acuerdo; ambos leen lo mismo, para mí. Sin embargo, en una interfaz de usuario para una persona laica, creo que sí/no se ve mejor. –

+14

No estoy de acuerdo también. En todo caso, se lee mal debido a que no se apega a los estándares no escritos que se han usado durante años en otros idiomas. IE es un excelente ejemplo de lo que sucede cuando no se cumple una gran cantidad de estándares. – FreeAsInBeer

+5

-1 por dejar dos respuestas que podrían enumerarse como una – Supuhstar

13

Es posible que desee leer las respuestas a esta question. En resumen, en Objective-C (a partir de la definición de objc.h):

typedef signed char  BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used. 
#define OBJC_BOOL_DEFINED 


#define YES    (BOOL)1 
#define NO    (BOOL)0 
90

Creo que hay es una diferencia entre bool y BOOL, echa un vistazo a la página para una explicación de por qué:
http://iosdevelopertips.com/objective-c/of-bool-and-yes.html

Debido BOOL es un unsigned char en lugar de un tipo primitivo, variables de tipo BOOL puede contener valores distintos de YES y NO.

consideran este código:

BOOL b = 42; 

if (b) { 
    printf("b is not NO!\n"); 
} 

if (b != YES) { 
    printf("b is not YES!\n"); 
} 

La salida es:

b no hay!
¡b no es SÍ!

Para la mayoría de las personas esto es una preocupación innecesaria, pero si realmente quiere un booleano, es mejor usar un bool. Debo añadir: el SDK de iOS generalmente usa BOOL en sus definiciones de interfaz, por lo que es un argumento para quedarse con BOOL.

+4

Pero tenga en cuenta que la implementación C original no tenía 'bool', y por lo tanto ha sido una tradición usar' int' o 'char' como booleano, a veces con un #define para ocultar la diferencia y otras no. De hecho, no estoy seguro si incluso los estándares actuales requieren que 'bool' se implemente de una manera que impida examinar su estructura interna. –

+1

Aunque, el primer 'printf' dice mentiras. El valor de 'b' no es' SÍ', es "no cero", que es lo que comprueba la condición. Entonces debería tener 'printf (" b no es cero ")', que no es necesariamente lo mismo que 'SÍ'. En este caso, 'b' es" no cero "y" no SÍ ". –

+0

Gracias Lawrence, he hecho una actualización en ese sentido. –

46

Hice una prueba exhaustiva de esto. Mis resultados deben hablan por sí mismos:

//These will all print "1" 
NSLog(@"%d", true == true); 
NSLog(@"%d", TRUE == true); 
NSLog(@"%d", YES == true); 
NSLog(@"%d", true == TRUE); 
NSLog(@"%d", TRUE == TRUE); 
NSLog(@"%d", YES == TRUE); 
NSLog(@"%d", true == YES); 
NSLog(@"%d", TRUE == YES); 
NSLog(@"%d", YES == YES); 

NSLog(@"%d", false == false); 
NSLog(@"%d", FALSE == false); 
NSLog(@"%d", NO == false); 
NSLog(@"%d", false == FALSE); 
NSLog(@"%d", FALSE == FALSE); 
NSLog(@"%d", NO == FALSE); 
NSLog(@"%d", false == NO); 
NSLog(@"%d", FALSE == NO); 
NSLog(@"%d", NO == NO); 


//These will all print "0" 
NSLog(@"%d", false == true); 
NSLog(@"%d", FALSE == true); 
NSLog(@"%d", NO == true); 
NSLog(@"%d", false == TRUE); 
NSLog(@"%d", FALSE == TRUE); 
NSLog(@"%d", NO == TRUE); 
NSLog(@"%d", false == YES); 
NSLog(@"%d", FALSE == YES); 
NSLog(@"%d", NO == YES); 

NSLog(@"%d", true == false); 
NSLog(@"%d", TRUE == false); 
NSLog(@"%d", YES == false); 
NSLog(@"%d", true == FALSE); 
NSLog(@"%d", TRUE == FALSE); 
NSLog(@"%d", YES == FALSE); 
NSLog(@"%d", true == NO); 
NSLog(@"%d", TRUE == NO); 
NSLog(@"%d", YES == NO); 

La salida es:

2013-02-19 20:30:37.061 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.061 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.072 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.073 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.073 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.074 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.074 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.075 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.075 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.076 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.077 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.077 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.078 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.078 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.079 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.079 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.080 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.080 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.081 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.081 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.082 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.091 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.092 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.093 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.093 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.094 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.094 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.095 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.095 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.096 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.096 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.097 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.098 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.101 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.102 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.102 BooleanTests[27433:a0f] 0 
+3

[[NSObject] alloc] init] no es igual a TRUE o YES. Por lo tanto, la prueba de inicialización de objetos con if ([[NSObject] alloc] init] == ​​TRUE) fallará. Nunca me he sentido cómodo con un lenguaje que define un valor "verdadero" singular cuando de hecho cualquier valor distinto de cero servirá. –

+2

@SamuelRenkert Nunca me he sentido cómodo con un lenguaje que toma un valor no booleano en un 'si' o en un' while'. Como ... 'while (" la guitarra llora gentilmente ")' no debería funcionar ... – Supuhstar

+0

@SamuelRenkert también la puerta trasera de Linux que se encontró en 2003: 'if (user_id = ROOT_UID)' – Supuhstar

0

hay un error sutil que nadie ha mencionado aquí, que yo pensaba que iba a incluir ... más de una lógica de error que cualquier otra cosa:

int i = 2; 
if(i);  //true 
if(i==YES); // false 
if((!!i)==YES); //true 

por lo que la cuestión aquí es sólo eso (YES==1) y en C la comparación no es un booleano, pero uno basado en el valor.

porque YES es sólo un #define (en lugar de algo intrínseco al lenguaje), que tiene que ser algún valor, y 1 que tiene más sentido.

+0

Esta es esencialmente la misma respuesta que DanJ's, desde 2+ años antes, con menos detalles. –

+0

@LawrenceDol No sé, menciona que SÍ solo está #definido para ser 1 y no intrínseco al lenguaje, como podría ser en un lenguaje de nivel superior ... alguien podría obtener un valor de eso ... pero buen trolling, contigo. –

4

La principal (¡peligrosa!) Diferencia entre true y YES se encuentra en la serialización JSON.

Por ejemplo, tenemos petición del servidor de tipo JSON y necesitamos enviar verdadero/falso en SENCE JSON:

NSDictionary *r1 = @{@"bool" : @(true)}; 
NSDictionary *r2 = @{@"bool" : @(YES)}; 
NSDictionary *r3 = @{@"bool" : @((BOOL)true)}; 

Luego convertirlo a cadena JSON antes de enviar como

NSData *data = [NSJSONSerialization dataWithJSONObject:requestParams options:0 error:nil]; 
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

El resultado es

jsonString1 // {"bool":1} 
jsonString2 // {"bool":true} 
jsonString3 // {"bool":true} 

Debido a la lógica API jsonString1 podría resultar en un error.

Tenga cuidado con los booleanos en Objective-C.

P.S. Puede usar

@{@"bool" : @"true"}; // {"bool":true} 
Cuestiones relacionadas