160

真的很简单的问题;这些值之间是否存在差异(BOOL 和 bool 之间是否存在差异)?一位同事提到他们在 Objective-C 中评估不同的东西,但是当我查看他们各自 .h 文件中的 typedef 时,YES/TRUE/true 都被定义为1,NO/FALSE/false 都被定义为0。真的有什么区别吗?

4

9 回答 9

102

我相信和之间区别boolBOOL请查看此网页以了解原因:http:
//iosdevelopertips.com/objective-c/of-bool-and-yes.html

因为BOOL是一种unsigned char而不是原始类型,所以类型的变量BOOL可以包含 和 以外YES的值NO

考虑这段代码:

BOOL b = 42;

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

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

输出是:

b 不是 NO!
b 不是 YES!

对于大多数人来说,这是一个不必要的问题,但如果你真的想要一个布尔值,最好使用bool. 我应该补充一点:iOS SDK 通常BOOL在其接口定义上使用,所以这是一个坚持使用BOOL.

于 2011-03-29T12:45:52.737 回答
84

如果您将BOOL变量用作布尔值,则没有实际区别。C 根据布尔表达式的计算结果是否为 0 来处理布尔表达式。所以:

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

意思是一样的

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

这就是为什么您可以将任何原始类型或表达式评估为布尔测试(包括,例如指针)。请注意,您应该做前者,而不是后者。

请注意,如果将钝值分配给所谓的变量并测试特定值,则会BOOL有所不同,因此请始终将它们用作布尔值并仅从它们的#define值中分配它们。

重要的是,永远不要使用字符比较来测试布尔值——这不仅是有风险的,因为someVar可以分配一个不是 YES 的非零值,而且在我看来更重要的是,它无法正确表达意图:

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

换句话说,按照预期和记录使用的构造来使用,您将避免在 C 语言中受到伤害。

于 2009-03-05T17:22:41.550 回答
55

我对此进行了详尽的测试。我的结果应该不言自明:

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

输出是:

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
于 2013-02-20T01:35:14.923 回答
14

您可能想阅读这个问题的答案。总之,在 Objective-C 中(来自 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
于 2009-03-05T17:57:23.433 回答
14

true和之间的主要(危险!)区别在于YESJSON 序列化。

例如,我们有 JSON 类型的服务器请求,需要在 json sence 中发送 true/false:

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

然后我们在发送之前将其转换为 JSON 字符串

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

结果是

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

由于 API 逻辑jsonString1可能导致错误。

所以要小心 Objective-C 中的布尔值。

总而言之,只有精确@YES和强制转换的值@((BOOL)expression)__NSCFBoolean类型并true使用 JSON 序列化转换为。任何其他表达式,如@(expression1 && expression2)(even @(YES && YES)) 都是__NSCFNumber (int)类型并转换为1JSON。

PS您可以简单地使用字符串值布尔值

@{@"bool" : @"true"}; // in JSON {"bool":true}
于 2016-05-14T12:41:56.127 回答
1

这里没有人提到一个微妙的错误,我想我会包括......更多的逻辑错误而不是任何东西:

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

所以这里的问题就是这样(YES==1),在 C 中,比较不是布尔值,而是基于值的比较。

因为YES它只是一个#define(而不是语言固有的东西),它必须具有某种价值,并且1最有意义。

于 2014-10-23T03:51:48.130 回答
0

我认为他们在许多情况下添加“是/否”以更加不言自明。例如:

[button setHidden:YES];

听起来比

[button setHidden:TRUE];
于 2009-03-05T17:29:25.120 回答
-3

首先,让我们检查一下什么是真假,以及是什么赋予了它们意义。

我们可以在 lambda 演算中构造一个名为 if a then b else c 的结构,如下所示:

(\ifThenElse. <use if then else>)(\a. \b. \c. a b c)

在 JavaScript 中,这看起来像这样:

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

为了使 ifThenElse 有用,我们需要一个选择右或左的函数“true”,并在忽略另一个选项的情况下执行此操作,或者选择不使用选项“true”的函数“false”。

我们可以如下定义这些函数:

(\true. <use true>)(\a. \b. a) and (\false. <use false>)(\a. \b. b)

在 JavaScript 中它看起来像这样:

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

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

现在我们可以执行以下操作

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

doThis 和 doThat 是 (\a. ()) 因为 lambda 演算不提供任何服务,例如打印/数学/字符串,我们所能做的就是什么都不做,说我们做到了(后来通过用服务替换它来作弊)我们的系统提供我们想要的副作用)

所以让我们看看这个在行动。

(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");})();

如果我们被允许使用数组/映射/参数/或多个语句来拆分为多个函数,那么这是一个可以简化的深层环境,但我想保持尽可能纯粹,因为我可以将自己限制为只有一个参数的函数只要。

请注意,名称 True/False 没有内在意义,我们可以轻松地将它们重命名为 yes/no、left/right、right/left、0/one、apple/orange。它的意义在于,无论做出什么选择,都只是由做出选择的人造成的。所以如果打印“LEFT”,我们知道选择器只能是真的,并且基于这些知识我们可以指导我们进一步的决定。

所以总结一下

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');
})();
于 2018-03-31T21:24:09.383 回答
-7

不,YES/NO 是指 TRUE/FALSE(1/0) 的不同方式

于 2009-03-05T17:12:08.517 回答