在Objective-c中,YES / NO,TRUE / FALSE和true / false之间是否有区别?

时间:2009-03-05 17:09:56

标签: objective-c boolean

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

9 个答案:

答案 0 :(得分:96)

我相信 <{1}}和bool之间存在差异,请查看此网页以获取解释原因:
http://iosdevelopertips.com/objective-c/of-bool-and-yes.html

由于BOOLBOOL而不是基本类型,因此unsigned char类型的变量可以包含BOOLYES以外的值。

考虑以下代码:

NO

输出结果为:

  

b不是NO!
  b不是!

对于大多数人来说,这是一个不必要的问题,但如果你真的想要一个布尔值,最好使用BOOL b = 42; if (b) { printf("b is not NO!\n"); } if (b != YES) { printf("b is not YES!\n"); } 。我应该补充一点:iOS SDK通常在其接口定义上使用bool,因此这是一个坚持BOOL的参数。

答案 1 :(得分:78)

提供 没有实际差异您使用BOOL变量作为布尔值。 C根据它们是否计算为0来处理布尔表达式。所以:

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

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

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

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

重要的是,永远不要使用字符比较来测试布尔值 - 它不仅有风险,因为someVar可以被赋予非零的非零值,但在我看来更重要的是,它无法表达意图正确:

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

换句话说,使用构造,因为它们是预期的并且有文件记录可供使用,你将使自己远离C语言中的伤害世界。

答案 2 :(得分:49)

我对此做了详尽的测试。我的结果应该说明一切:

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

答案 3 :(得分:14)

您可能想要阅读此question的答案。总之,在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

答案 4 :(得分:8)

trueYES之间的主要(危险!)区别在于JSON序列化。

例如,我们有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类型,并通过JSON序列化转换为true。 任何其他表达式,例如@(expression1 && expression2)(偶数@(YES && YES))都是__NSCFNumber (int)类型,并在JSON中转换为1

P.S。您可以简单地使用字符串值布尔值

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

答案 5 :(得分:1)

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

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

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

因为YES只是#define(而不是语言固有的东西),所以它必须是一些价值,而1最有意义。

答案 6 :(得分:0)

我认为他们在许多情况下加上YES / NO更加不言自明。例如:

[button setHidden:YES];

听起来比

[button setHidden:TRUE];

答案 7 :(得分:-2)

首先让我们先来看一下真​​假是什么,以及首先给出了什么意义。

我们可以构建一个结构,如果在lambda演算中是b,那么b,如下所示:

neural_network_model( x )

在JavaScript中,看起来像这样:

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

为了使ifThenElse有用,我们需要一个函数&#34; true&#34;选择向右或向左,并在忽略其他选项时执行此操作,或者选择函数&#34; false&#34;选择选项&#34; true&#34;没有。

我们可以按如下方式定义这些功能:

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

看起来像这样:

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

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

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

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

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

所以让我们看看这一点。

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

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

注意名称True / False没有内在意义,我们可以轻松地将它们重命名为yes / no,left / right,right / left,zero / one,apple / orange。无论做出何种选择,它都具有重要意义,它只是由选择者做出的选择造成的。所以如果&#34; LEFT&#34;印刷品,我们知道选择器只能是真实的,并且基于这些知识,我们可以指导我们的进一步决策。

总结

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

答案 8 :(得分:-7)

不,是/否是引用TRUE / FALSE(1/0)

的另一种方式