Simple question vraiment; Existe-t-il une différence entre ces valeurs (et existe-t-il une différence entre BOOL et bool)? Un collègue de travail a mentionné qu'il évaluait différentes choses dans Objective-C, mais lorsque j'ai examiné les types de caractères dans leurs fichiers .h respectifs, YES/TRUE/true ont tous été définis comme étant 1
et NO/FALSE/false ont tous été définis comme 0
. Y a-t-il vraiment une différence?
Il n'y a pas de différence pratique fourni vous utilisez BOOL
variables comme booléens. C traite les expressions booléennes selon qu’elles s’évaluent ou non à 0. Donc:
if(someVar ) { ... }
if(!someVar) { ... }
signifie la même chose que
if(someVar!=0) { ... }
if(someVar==0) { ... }
c’est pourquoi vous pouvez évaluer n’importe quel type ou expression primitif en tant que test booléen (y compris, par exemple, des pointeurs). Notez que vous devriez faire le premier, pas le dernier.
Notez qu'il y a est une différence si vous affectez des valeurs obtuses à une variable dite BOOL
et testez pour des valeurs spécifiques, utilisez-les toujours comme booléens et ne les affectez qu'à partir de leur #define
valeurs.
Il est important de ne jamais tester les booléens en utilisant une comparaison de caractères - ce n'est pas seulement risqué car someVar
pourrait se voir attribuer une valeur non nulle qui n'est pas OUI, mais, à mon avis plus important, il n'exprimait pas l'intention correctement :
if(someVar==YES) { ... } // don't do this!
if(someVar==NO ) { ... } // don't do this either!
En d'autres termes, utilisez les constructions telles qu'elles sont conçues et documentées, et vous vous épargnerez d'un monde de blessures en C.
Je crois qu’il existe une différence entre bool
et BOOL
, consultez cette page Web pour savoir pourquoi:
http://iosdevelopertips.com/objective-c/of-bool-and-yes.html
Parce que BOOL
est un unsigned char
plutôt que de type primitif, les variables de type BOOL
peuvent contenir des valeurs autres que YES
et NO
.
Considérons ce code:
BOOL b = 42;
if (b) {
printf("b is not NO!\n");
}
if (b != YES) {
printf("b is not YES!\n");
}
La sortie est:
b n'est pas NON!
b n'est pas OUI!
Pour la plupart des gens, c'est une préoccupation inutile, mais si vous voulez vraiment un booléen, il est préférable d'utiliser un bool
. Je devrais ajouter: le SDK iOS utilise généralement BOOL
dans ses définitions d'interface; il s'agit donc d'un argument à coller avec BOOL
.
J'ai fait un test exhaustif à ce sujet. Mes résultats devraient parler d'eux-mêmes:
//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 sortie est:
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
Vous voudrez peut-être lire les réponses à cette question question . En résumé, en Objective-C (d'après la définition dans 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
La principale différence (dangereuse!) Entre true
et YES
est dans la sérialisation JSON.
Par exemple, nous avons une requête de serveur de type JSON et devons envoyer true/false en json sence:
NSDictionary *r1 = @{@"bool" : @(true)};
NSDictionary *r2 = @{@"bool" : @(YES)};
NSDictionary *r3 = @{@"bool" : @((BOOL)true)};
Ensuite, nous le convertissons en chaîne JSON avant de l'envoyer en tant que
NSData *data = [NSJSONSerialization dataWithJSONObject:requestParams options:0 error:nil];
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
Le résultat est
jsonString1 // {"bool":1}
jsonString2 // {"bool":true}
jsonString3 // {"bool":true}
En raison de la logique de l'API, jsonString1
Peut entraîner une erreur.
Soyez donc prudent avec les booléens dans Objective-C.
En résumé, seuls @YES
Exact et la valeur exprimée sous la forme @((BOOL)expression)
sont de type __NSCFBoolean
Et convertis en true
avec sérialisation JSON. Toutes les autres expressions telles que @(expression1 && expression2)
(même @(YES && YES)
) sont de type __NSCFNumber (int)
et converties en 1
En JSON.
P.S. Vous pouvez simplement utiliser un booléen à valeur de chaîne
@{@"bool" : @"true"}; // in JSON {"bool":true}
Il y a un bug subtil que personne n'a mentionné ici, et que je pensais inclure… plus d'une erreur logique qu'autre chose:
int i = 2;
if(i); //true
if(i==YES); // false
if((!!i)==YES); //true
donc la question ici est juste que (YES==1)
et en C, la comparaison n’est pas une comparaison booléenne, mais une comparaison basée sur la valeur.
parce que YES
est juste un #define
(plutôt qu’une chose intrinsèque à la langue), il doit y avoir une valeur, et 1
a le plus de sens.
Je pense qu'ils ajoutent OUI/NON pour être plus explicites dans de nombreux cas. Par exemple:
[button setHidden:YES];
sonne mieux que
[button setHidden:TRUE];