web-dev-qa-db-fra.com

Existe-t-il une différence entre OUI / NON, VRAI / FAUX et vrai / faux dans objective-c?

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?

149
Kevlar

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.

81
Lawrence Dol

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.

97
Dan J

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
50
Supuhstar

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
14
Barry Wark

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}
10
malex

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.

1
Grady Player

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];
0
Marco