J'ai vu le "nouveau type" BOOL
(YES
, NO
).
J'ai lu que ce type est presque comme un char.
Pour tester j'ai fait:
NSLog(@"Size of BOOL %d", sizeof(BOOL));
NSLog(@"Size of bool %d", sizeof(bool));
Il est bon de voir que les deux journaux affichent "1" (parfois, en C++, bool est un entier et sa taille est de 4)
Alors je me demandais s'il y avait des problèmes avec le type bool ou quelque chose?
Puis-je simplement utiliser bool (qui semble fonctionner) sans perdre de vitesse?
De la définition dans 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)
Donc, oui, vous pouvez supposer que BOOL est un personnage. Vous pouvez utiliser le type (C99) bool
, mais tous les frameworks Objective-C d’Apple et la plupart du code Objective-C/Cocoa utilisent BOOL.
Comme mentionné ci-dessus, BOOL est un caractère signé. bool - type de C99 standard (int).
BOOL - OUI/NON bool - vrai/faux.
Voir des exemples:
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");
Et le résultat est
REAL b1
REAL b2
NOT REAL b2
Notez que bool! = BOOL. Le résultat ci-dessous est seulement NE FOIS ENCORE - REAL b2
b2 = b1;
if (b2) printf("ONCE AGAIN - REAL b2 \n");
if (b2 != true) printf("ONCE AGAIN - NOT REAL b2 \n");
Si vous voulez convertir bool en BOOL, vous devez utiliser le code suivant
BOOL b22 = b1 ? YES : NO; //and back - bool b11 = b2 ? true : false;
Donc, dans notre cas:
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");
Et alors .. qu'est-ce qu'on a maintenant? :-)
Au moment de la rédaction de ce document, il s'agit de la version la plus récente 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
Cela signifie que sur les appareils iOS 64 bits et sur WatchOS BOOL
est exactement la même chose que bool
alors que sur tous les autres appareils (OS X, iOS 32 bits), il s'agit de signed char
et ne peut même pas être écrasé par le drapeau du compilateur -funsigned-char
Cela signifie également que cet exemple de code fonctionnera différemment sur différentes plates-formes (testé moi-même):
int myValue = 256;
BOOL myBool = myValue;
if (myBool) {
printf("i'm 64-bit iOS");
} else {
printf("i'm 32-bit iOS");
}
BTW n'assigne jamais des choses comme array.count
à BOOL
variable car environ 0,4% des valeurs possibles seront négatives.
Le type d'Objective-C que vous devriez utiliser est BOOL
. Il n'y a rien de tel qu'un type de données booléen natif, donc pour être sûr que le code compile sur tous les compilateurs, utilisez BOOL
. (Il est défini dans les cadres Apple.
Yup, BOOL est un typedef pour un caractère signé selon objc.h.
Je ne sais pas pour bool, cependant. C'est une chose C++, non? S'il est défini comme un caractère signé où 1 correspond à OUI/vrai et 0 à NON/faux, alors j'imagine que le type que vous utilisiez importe peu.
Puisque BOOL fait partie d’Objective-C, il est probablement plus logique d’utiliser un objet BOOL pour plus de clarté (d’autres développeurs d’Objective-C pourraient être perplexes s’ils voient un booléen en cours d’utilisation).
Une autre différence entre bool et BOOL est qu’ils ne convertissent pas exactement dans le même type d’objets, que vous observiez des valeurs-clés ou que vous utilisiez des méthodes telles que - [NSObject valueForKey:].
Comme tout le monde l’a dit, BOOL, c’est char. En tant que tel, il est converti en un NSNumber avec un caractère. Cet objet ne peut pas être distingué d'un NSNumber créé à partir d'un caractère normal tel que 'A' ou '\ 0'. Vous avez totalement perdu l'information selon laquelle vous aviez initialement un BOOL.
Cependant, bool est converti en CFBoolean, qui se comporte de la même manière que NSNumber, mais qui conserve l'origine booléenne de l'objet.
Je ne pense pas que ce soit un argument dans un débat BOOL vs. bool, mais cela risque de vous piquer un jour.
De manière générale, vous devriez aller avec BOOL, car c'est le type utilisé partout dans les API Cocoa/iOS (conçu avant C99 et son type bool natif).
La réponse acceptée a été modifiée et son explication devient un peu incorrecte. L'échantillon de code a été actualisé, mais le texte ci-dessous reste le même. Vous ne pouvez pas supposer que BOOL est un caractère pour le moment, car cela dépend de l'architecture et de la plate-forme. Ainsi, si vous exécutez votre code sur une plate-forme 32 bits (par exemple, iPhone 5) et imprimez @encode (BOOL), vous verrez "c". Cela correspond à un type de caractère . Mais si vous exécutez votre code sur l'iPhone 5s (64 bits), vous verrez "B". Cela correspond à un type bool .
Comme mentionné ci-dessus, BOOL
pourrait être un type unsigned char
en fonction de votre architecture, alors que bool
est du type int
. Une expérience simple montrera la différence pourquoi BOOL et bool peuvent se comporter différemment:
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);
À votre grande surprise, if(objcBOOL != YES)
sera évalué à 1 par le compilateur, puisque YES
est en fait le code de caractère 1, et aux yeux du compilateur, le code de caractère 64 est bien sûr pas égal au code de caractère 1 ainsi l'instruction if sera évaluée à YES/true/1
et la ligne suivante sera exécutée. Toutefois, puisqu’un type non nul bool
renvoie toujours la valeur entière de 1, le problème ci-dessus n’affectera pas votre code. Voici quelques bons conseils si vous souhaitez utiliser le type Objective-C BOOL
contre le type ANSI C bool
:
YES
ou NO
et rien d'autre.BOOL
à l'aide de l'opérateur double not !!
afin d'éviter des résultats inattendus.YES
, utilisez if(!myBool) instead of if(myBool != YES)
, il est beaucoup plus propre d'utiliser l'opérateur not !
et donne le résultat attendu.Je vais contre la convention ici. Je n'aime pas les typedef à base de types. Je pense que c'est une indirection inutile qui supprime la valeur.
Tenez également compte des différences de transtypage, en particulier lorsque vous travaillez avec des bitmasks, en raison du transtypage en caractères signés:
bool a = 0x0100;
a == true; // expression true
BOOL b = 0x0100;
b == false; // expression true on !((TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH), e.g. MacOS
b == true; // expression true on (TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH
Si BOOL est un caractère signé au lieu d'un booléen, la conversion de 0x0100 en BOOL supprime simplement le bit défini et la valeur résultante est 0.