Objetivo-C: BOOL vs bool


Vi el "nuevo tipo" BOOL (YES, NO).

Leí que este tipo es casi como un char.

Para probar lo hice:

NSLog(@"Size of BOOL %d", sizeof(BOOL));
NSLog(@"Size of bool %d", sizeof(bool));

Es bueno ver que ambos registros muestran "1" (a veces en C++ bool es un int y su tamaño es 4)

Así que me preguntaba si había algunos problemas con el tipo bool o algo así.

¿Puedo usar bool (que parece funcionar) sin perder velocidad?

Author: Arslan Ali, 2009-02-12

9 answers

De la definición en objc.h:

#if (TARGET_OS_IPHONE && __LP64__)  ||  TARGET_OS_WATCH
typedef bool BOOL;
#else
typedef signed char BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used.
#endif

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

Así que, sí, puedes asumir que BOOL es un char. Puedes usar el tipo (C99) bool, pero todos los frameworks Objective-C de Apple y la mayoría del código Objective-C/Cocoa usan BOOL, por lo que te ahorrarás dolor de cabeza si el typedef cambia con solo usar BOOL.

 191
Author: Barry Wark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-08 16:00:30

Como se mencionó anteriormente, BOOL es un carácter firmado. bool-tipo del estándar C99 (int).

BOOL - SÍ/NO. bool - verdadero/falso.

Ver ejemplos:

bool b1 = 2;
if (b1) printf("REAL b1 \n");
if (b1 != true) printf("NOT REAL b1 \n");

BOOL b2 = 2;
if (b2) printf("REAL b2 \n");
if (b2 != YES) printf("NOT REAL b2 \n");

Y el resultado es

B1 REAL
b2 REAL
B2 NO REAL

Tenga en cuenta que bool != BOOL. El resultado a continuación es solo UNA VEZ MÁS - b2 REAL

b2 = b1;
if (b2) printf("ONCE AGAIN - REAL b2 \n");
if (b2 != true) printf("ONCE AGAIN - NOT REAL b2 \n");

Si desea convertir bool a BOOL debe usar el siguiente código

BOOL b22 = b1 ? YES : NO; //and back - bool b11 = b2 ? true : false;

Así, en nuestro caso:

BOOL b22 = b1 ? 2 : NO;
if (b22)    printf("ONCE AGAIN MORE - REAL b22 \n");
if (b22 != YES) printf("ONCE AGAIN MORE- NOT REAL b22 \n");

Y así.. ¿qué tenemos ahora? :-)

 32
Author: beryllium,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-22 09:01:43

En el momento de escribir esta es la versión más reciente de objc.h:

/// Type to represent a boolean value.
#if (TARGET_OS_IPHONE && __LP64__)  ||  TARGET_OS_WATCH
#define OBJC_BOOL_IS_BOOL 1
typedef bool BOOL;
#else
#define OBJC_BOOL_IS_CHAR 1
typedef signed char BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used.
#endif

Significa que en dispositivos iOS de 64 bits y en watchOS BOOL es exactamente lo mismo que bool mientras que en todos los demás dispositivos (OS X, iOS de 32 bits) es signed char y ni siquiera puede ser anulado por compiler flag -funsigned-char

También significa que este código de ejemplo se ejecutará de manera diferente en diferentes plataformas (lo probé yo mismo):

int myValue = 256;
BOOL myBool = myValue;
if (myBool) {
    printf("i'm 64-bit iOS");
} else {
    printf("i'm 32-bit iOS");
}

Por cierto, nunca asigne cosas como array.count a BOOL variable porque alrededor del 0.4% de los posibles valores serán negativos.

 11
Author: Tobol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-30 15:24:43

El tipo Objective-C que debe usar es BOOL. No hay nada como un tipo de datos booleano nativo, por lo tanto para estar seguro de que el código se compila en todos los compiladores use BOOL. (Se define en Apple-Frameworks.

 8
Author: Georg Schölly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-12 14:08:32

Sí, BOOL es un typedef para un carácter firmado según objc.h.

No se sobre Bool, sin embargo. Eso es una cosa de C++, ¿verdad? Si se define como un carácter firmado donde 1 es SÍ/verdadero y 0 es NO/falso, entonces imagino que no importa cuál use.

Dado que BOOL es parte de Objective-C, sin embargo, probablemente tenga más sentido usar un BOOL para mayor claridad (otros desarrolladores de Objective-C podrían estar desconcertados si ven un bool en uso).

 5
Author: Jeff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-12 14:02:00

Otra diferencia entre bool y BOOL es que no convierten exactamente al mismo tipo de objetos, cuando se observa clave-valor, o cuando se usan métodos como -[NSObject valueForKey:].

Como todo el mundo ha dicho aquí, BOOL es char. Como tal, se convierte en un NSNumber que contiene un char. Este objeto es indistinguible de un NSNumber creado a partir de un carácter regular como 'A' o '\0'. Has perdido totalmente la información de que originalmente tenías un BOOL.

Sin embargo, bool se convierte a un cfbooleano, que se comporta igual que NSNumber, pero que conserva el origen booleano del objeto.

No creo que este es un argumento en un BOOL vs bool debate, pero esto puede morder un día.

En términos generales, debe ir con BOOL, ya que este es el tipo utilizado en todas partes en las API Cocoa/iOS (diseñado antes de C99 y su tipo bool nativo).

 4
Author: Gwendal Roué,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-08 08:12:46

La respuesta aceptada ha sido editada y su explicación se ha vuelto un poco incorrecta. El ejemplo de código se ha actualizado, pero el texto a continuación sigue siendo el mismo. No puede asumir que BOOL es un char por ahora, ya que depende de la arquitectura y la plataforma. Por lo tanto, si ejecuta su código en la plataforma de 32 bits(por ejemplo, iPhone 5) e imprime @encode(BOOL) verá "c". Corresponde a un tipo char. Pero si ejecuta el código en el iPhone 5s (64 bits) verá "B". Corresponde a un bool tipo.

 2
Author: curious,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-13 13:20:10

Estoy en contra de lo convencional. No me gusta typedef para tipos de base. Creo que es una indirecta inútil que quita valor.

  1. Cuando vea el tipo base en su fuente lo entenderé instantáneamente. Si es un typedef tengo que buscarlo para ver con lo que realmente estoy tratando.
  2. Al portar a otro compilador o agregar otra biblioteca, su conjunto de typedefs puede entrar en conflicto y causar problemas que son difíciles de depurar. Acabo de terminar de lidiar con esto, de hecho. En uno biblioteca booleano fue typedef ed a int, y en mingw/gcc es typedef ed a un char.
 1
Author: Jay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-05 17:15:51

Como se mencionó anteriormente BOOL podría ser un tipo unsigned char dependiendo de su arquitectura, mientras que bool es de tipo int. Un experimento simple mostrará la diferencia por qué BOOL y bool pueden comportarse de manera diferente:

bool ansicBool = 64;
if(ansicBool != true) printf("This will not print\n");

printf("Any given vlaue other than 0 to ansicBool is evaluated to %i\n", ansicBool);

BOOL objcBOOL = 64;
if(objcBOOL != YES) printf("This might print depnding on your architecture\n");

printf("BOOL will keep whatever value you assign it: %i\n", objcBOOL);

if(!objcBOOL) printf("This will not print\n");

printf("! operator will zero objcBOOL %i\n", !objcBOOL);

if(!!objcBOOL) printf("!! will evaluate objcBOOL value to %i\n", !!objcBOOL);

Para su sorpresa if(objcBOOL != YES) evaluará a 1 por el compilador, ya que YES es en realidad el código de caracteres 1, y a los ojos del compilador, el código de caracteres 64 es, por supuesto, no es igual al código de caracteres 1 por lo tanto, la declaración if evaluará a YES/true/1 y la siguiente línea se ejecutará. Sin embargo, dado que un tipo none zero bool siempre se evalúa al valor entero de 1, el problema anterior no afectará su código. A continuación se presentan algunos buenos consejos si desea utilizar el tipo Objective-C BOOL vs el tipo ANSI C bool:

  • Siempre asigne el valor YES o NO y nada más.
  • Convierta los tipos BOOL usando el operador double not !! para evitar resultados inesperados.
  • Al verificar YES use if(!myBool) instead of if(myBool != YES) es mucho más limpio usar el no ! operador y da el resultado esperado.
 1
Author: ilgaar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-11 22:51:26