Existe uma diferença entre SIM / NÃO, VERDADEIRO / FALSO e verdadeiro / falso no objective-c?

Pergunta simples realmente; Existe uma diferença entre esses valores (e existe uma diferença entre BOOL e bool)? Um colega mencionou que eles avaliam coisas diferentes em Objective-C, mas quando eu olhei para os typedefs em seus respectivos arquivos .h, YES / TRUE / true foram todos definidos como 1 e NO / FALSE / false foram todos definidos como 0 Existe realmente alguma diferença?

Não há diferença prática, desde que você use variables BOOL como booleanas. C processa expressões booleanas com base em se elas avaliam 0 ou não 0. Então:

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

significa o mesmo que

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

é por isso que você pode avaliar qualquer tipo ou expressão primitiva como um teste booleano (incluindo, por exemplo, pointers). Note que você deve fazer o primeiro, não o último.

Note que há uma diferença se você atribuir valores obtusos a uma variável BOOL e testar valores específicos, portanto use-os sempre como valores booleanos e atribua-os somente a partir de seus valores #define .

É importante someVar nunca testar valores booleanos usando uma comparação de caracteres – não é apenas arriscado, porque someVar pode receber um valor diferente de zero, que não é YES, mas, na minha opinião mais importante, falha em expressar a intenção corretamente:

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

Em outras palavras, use construções como elas são planejadas e documentadas para serem usadas e você se poupará de um mundo de dor em C.

Eu acredito que há uma diferença entre bool e BOOL , confira esta página para uma explicação do porquê:
http://iosdevelopertips.com/objective-c/of-bool-and-yes.html

Como BOOL é um unsigned char vez de um tipo primitivo, as variables ​​do tipo BOOL podem conter valores diferentes de YES e NO .

Considere este código:

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

A saída é:

b não é NÃO!
b não é sim!

Para a maioria das pessoas isso é uma preocupação desnecessária, mas se você realmente quer um booleano, é melhor usar um bool . Devo acrescentar: o SDK do iOS geralmente usa BOOL em suas definições de interface, de modo que é um argumento para ficar com BOOL .

Eu fiz um teste exaustivo sobre isso. Meus resultados devem falar por si:

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

A saída é:

 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 

Você pode querer ler as respostas para essa pergunta . Em resumo, em Objective-C (da definição em 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 

A diferença principal (perigosa!) Entre true e YES é na serialização JSON.

Por exemplo, temos solicitação de servidor do tipo JSON e precisamos enviar verdadeiro / falso no json sence:

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

Em seguida, convertemos para string JSON antes de enviar como

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

O resultado é

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

Devido à lógica da API, jsonString1 pode resultar em erro.

Portanto, tenha cuidado com booleanos em Objective-C.

PS Você pode usar

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

Eu acho que eles acrescentam SIM / NÃO para serem mais autoexplicativos em muitos casos. Por exemplo:

 [button setHidden:YES]; 

soa melhor do que

 [button setHidden:TRUE]; 

Há um bug sutil que ninguém mencionou aqui, que eu pensei que includeia … mais um erro lógico do que qualquer coisa:

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

então a questão aqui é apenas isso (YES==1) e em C a comparação não é booleana, mas sim baseada em valor.

porque o YES é apenas um #define (em vez de algo intrínseco à linguagem), tem que ter algum valor e 1 faz mais sentido.

Primeiro, vamos examinar o que é verdadeiro e falso e o que lhes dá significado em primeiro lugar.

podemos construir uma estrutura chamada if a then b else c em lambda calculus da seguinte maneira:

 (\ifThenElse. )(\a. \b. \c. abc) 

Em JavaScript, isto parece com isto:

 (function(ifThenElse) { // use ifThenElse })(function(a) { return function(b) { return function(c) { return a(b)(c); }; }; }); 

para que ifThenElse seja útil, precisamos de uma function “true” que escolha direita ou esquerda, e faça isso ignorando a outra opção, ou uma function “false” que escolha a opção “true”.

Podemos definir essas funções da seguinte forma:

 (\true. )(\a. \b. a) and (\false. )(\a. \b. b) 

em JavaScript parece com isso:

 (function(True) { // use True })(function(a) { return function(b) { return a; } }); (function(False) { // use True })(function(a) { return function(b) { return b; } }); 

agora podemos fazer o seguinte

 (\true. \false. \ifThenElse. \doThis. \doThat. ifThenElse true doThis doThat) (\a. \b. a)(\a. \b. b)(\a. \b. \c. abc)(\a. ())(\a. ()) 

com doThis e doThat sendo (\ a. ()) porque lambda calculus não oferece nenhum serviço como impressão / matemática / strings, tudo o que podemos fazer é não fazer nada e dizer que o fizemos (e depois trapacear substituindo-o por serviços em nosso sistema que fornece efeitos colaterais que queremos)

então vamos ver isso em ação.

 (function(True) { return (function(False) { return (function(ifThenElse) { return (function(doThis) { return (function(doThat) { return ifThenElse(True)(doThis)(doThat); }); }); }); }) })(function(a) { return function(b) { return a; } })(function(a) { return function(b) { return b; } })(function(a) { return function(b) { return function(c) { return a(b)(c); }; }; })(function(a) { console.log("you chose LEFT!"); }) (function(a) {console.log("you chose RIGHT");})(); 

Esse é um ambiente profundo que poderia ser simplificado se tivéssemos permissão para usar arrays / maps / arguments / ou mais de uma instrução para dividir em múltiplas funções, mas eu quero manter é tão puro quanto eu posso me limitar a funções de exatamente um argumento só.

note que o nome True / False não tem significado inerente, podemos facilmente renomeá-los para sim / não, esquerda / direita, direita / esquerda, zero / um, maçã / laranja. É importante que, seja qual for a escolha, ela é causada apenas pelo tipo de escolha feita. Então, se “LEFT” for impresso, sabemos que o seletor só pode ser verdadeiro e, com base nesse conhecimento, podemos orientar nossas decisões futuras.

Então, para resumir

 function ChooseRight(left) { return function _ChooseRight_inner(right) { return right; } } function ChooseLeft(left) { return function _ChooseLeft_inner(right) { return left; } } var env = { '0': ChooseLeft, '1': ChooseRight, 'false': ChooseRight, 'true': ChooseLeft, 'no': ChooseRight 'yes': ChooseLeft, 'snd': ChooseRight, 'fst': ChooseLeft }; var _0 = env['0']; var _1 = env['1']; var _true = env['true']; var _false = env['false']; var yes = env['yes']; var no = env['no']; // encodes church zero or one to boolean function lambda_encodeBoolean(self) { return self(false)(true); } // decodes a Boolean to church zero or one function lambda_decodeBoolean(self) { console.log(self, self ? env['true'] : env['false']); return self ? env['true'] : env['false']; } lambda_decodeBoolean('one' === 'two')(function() { console.log('one is two'); })(function() { console.log('one is not two'); })(); lambda_decodeBoolean('one' === 'one')(function() { console.log('one is one'); })(function() { console.log('one is not one'); })(); 

Não, SIM / NÃO é uma maneira diferente de se referir a VERDADEIRO / FALSO (1/0)