2009-03-05 20 views
135

Semplice domanda davvero; c'è una differenza tra questi valori (e c'è una differenza tra BOOL e bool)? Un collega ha affermato di valutare cose diverse in Objective-C, ma quando ho guardato i typedef nei loro rispettivi file .h, YES/TRUE/true erano tutti definiti come 1 e NO/FALSE/false erano tutti definiti come 0. C'è davvero qualche differenza?C'è una differenza tra SÌ/NO, VERO/FALSO e vero/falso nell'obiettivo-c?

+4

Dal punto di vista pratico non vi è alcuna differenza. Probabilmente puoi fare vari accorgimenti per dimostrare una differenza, ma generalmente ti stai allontanando dal territorio del "comportamento indefinito". –

risposta

70

Non v'è alcuna differenza pratica fornito si utilizza BOOL come variabili booleani. C elabora espressioni booleane in base al fatto che restituiscono 0 o non 0. Quindi:

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

lo stesso significato

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

che è il motivo per cui è possibile valutare qualsiasi tipo primitivo o un'espressione come un test booleano (compresi, ad esempio, i puntatori). Nota che dovresti fare il primo, non il secondo.

noti che ci è una differenza se si assegna valori ottusi ad una cosiddetta BOOL variabile e prova per i valori specifici, in modo sempre utilizzarli come booleani e solo li assegnano dai loro #define valori. Importante, non testare mai i booleani usando un confronto di caratteri - non è solo rischioso perché someVar potrebbe essere assegnato un valore diverso da zero che non è SÌ, ma, a mio avviso, più importante, non riesce a esprimere correttamente l'intento:

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

in altre parole, utilizzare costrutti come essi sono destinati e documentate da usare e ti risparmiano se stessi da un mondo di male in C.

-7

No, SI/NO è un modo diverso di fare riferimento a VERO/FALSO (1/0)

+3

-1 per non dire perché – Supuhstar

+3

-1 per non specificare – vilanovi

1

credo che aggiungere YES/NO per essere più autoesplicativo in molti casi. Per esempio:

[button setHidden:YES]; 

suona meglio di

[button setHidden:TRUE]; 
+1

Non sono d'accordo; entrambi hanno letto la stessa cosa, per me. Tuttavia, in un'interfaccia utente per un laico penso che Sì/No sia più bello. –

+14

Non sono d'accordo. Se non altro, si legge male a causa di non attenersi agli standard non scritti che sono stati utilizzati per anni in altre lingue. IE è un ottimo esempio di ciò che accade quando non riesci a rispettare un gran numero di standard. – FreeAsInBeer

+5

-1 per lasciare due risposte che potrebbero essere elencate come una – Supuhstar

13

si potrebbe desiderare di leggere le risposte a questo question. In sintesi, in Objective-C (dalla definizione in 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

Credo che ci è una differenza tra bool e BOOL, controlla il sito per una spiegazione del perché:
http://iosdevelopertips.com/objective-c/of-bool-and-yes.html

Poiché BOOL è un unsigned char piuttosto che un tipo primitivo, variabili di tipo BOOL possono contenere valori diversi YES e NO.

Considerate questo codice:

BOOL b = 42; 

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

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

L'output è:

B non è no!
b non è SÌ!

Per molte persone questo è una preoccupazione inutile, ma se si vuole veramente un valore booleano è meglio usare un bool. Dovrei aggiungere: l'SDK di iOS generalmente usa BOOL sulle sue definizioni di interfaccia, quindi questo è un argomento da rispettare con BOOL.

+4

Ma nota che l'implementazione C originale non aveva 'bool', e quindi è stata tradizione usare un' int' o 'char' come booleano, a volte con un #define per nascondere la differenza e talvolta no. In effetti, non sono sicuro che anche gli standard attuali richiedano il 'bool' per essere implementato in un modo che impedisca di esaminare la sua struttura interna. –

+1

Anche se il primo 'printf' dice bugie. Il valore di 'b' non è' SÌ', è "non zero", che è ciò che prova la condizione. Quindi dovresti avere 'printf (" b non è zero ")', che non è necessariamente uguale a 'SÌ'. In questo caso, 'b' è sia" non zero "che" non SÌ ". –

+0

Grazie Lawrence, ho fatto un aggiornamento lungo quelle linee. –

46

Ho fatto un test esauriente su questo. I miei risultati dovrebbero parlano da soli:

//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); 

L'output è:

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] non è uguale a TRUE o YES. Quindi testare l'inizializzazione dell'oggetto con if ([[NSObject] alloc] init] == ​​TRUE) avrà esito negativo. Non sono mai stato a mio agio con un linguaggio che definisce un valore "vero" singolare quando in realtà qualsiasi valore diverso da zero lo farà. –

+2

@SamuelRenkert Non mi sono mai sentito a mio agio con una lingua che assume un valore non booleano in un 'se' o un' while'. Come ... 'mentre (" la chitarra piange delicatamente ")' non dovrebbe funzionare ... – Supuhstar

+0

@SamuelRenkert anche la backdoor Linux che è stata trovata nel 2003: 'if (user_id = ROOT_UID)' – Supuhstar

0

C'è una sottile bug che nessuno ha menzionato qui, che ho pensato di includere ... più di una logica errore di ogni altra cosa:

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

in modo che il problema qui è proprio questo (YES==1) e in C il confronto non è un booleano, ma in base al valore.

perché YES è solo un #define (piuttosto che qualcosa di intrinseco al linguaggio), deve essere un certo valore, e 1 ha più senso.

+0

Questa è essenzialmente la stessa risposta di DanJ's, a partire da 2 anni prima, con meno dettagli. –

+0

@LawrenceDol Non lo so, si accenna che SÌ è solo # definito per essere 1 e non intrinseco al linguaggio, come potrebbe essere in un linguaggio di livello superiore ... qualcuno potrebbe ottenere valore da questo ... ma bravo trolling, con te. –

4

La differenza principale (pericolosa!) Tra true e YES è nella serializzazione JSON.

Ad esempio, abbiamo richiesta del server JSON-tipo e bisogno di inviare vero/falso in JSON sence:

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

Poi abbiamo convertirlo in stringa JSON prima di inviare come

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

Il risultato è

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

causa logica API jsonString1 potrebbe provocare un errore.

Quindi fai attenzione ai booleani in Objective-C.

P.S. È possibile utilizzare

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