BOOL对于我们来说,再熟悉不过了,但是,你真的会用BOOL吗?哈哈,没别的意思,只是想说明BOOL其实还有点坑。也许你拥有多年的开发经验,有可能在开发中会因BOOL导致错误。哈哈,有可能你现在在想,BOOL 不就是 真(1)与假(0)的区别嘛,会有什么坑呢?或者 你会想,我是不是在乱说呢?。不要着急,请听我细细说来。希望我下面的介绍会给你带来启示。
BOOL & bool
我们都知道 BOOL 被定义在 Objective-C中(注意,在64-bit 的iOS设备或者模拟器上已经把BOOL定义成了bool,因此以下我们考虑其他平台,包括运行实例)。bool这种类型的布尔,出现在古老的C语言中。但是BOOL实际上是一种对带符号类型(signed char)的类型定义,它拥有 8 bits的存储空间。通过#define指令把YES定义为1,NO定义为0。Objective-C并不会将BOOL作为仅能保存YES或NO值的真正布尔类型来处理。编译器仍将BOOL看作为8 bits二进制数。YES和NO值只是在习惯上的一种理解,同时也是为了与C语言中的false和true区别与一致。
在Objective-C中是这样定义的:
1 |
|
而bool就两个值0和非0,其实是一种(int)整型,即0代表false,非0代表为true.简单的描述下应该是这样定义:
1 |
|
具体定义请谷歌一下。也许有人说bool应该是0和1.请不用纠结这个问题,这个问题源于c语言的版本问题。在C语言标准(C98)并没有定义布尔类型,所以判断真假以0为假,非0为真,而在C99中,解决了布尔类型的问题。_Bool(bool)变量只能赋值为0或1.非0的值都被存储为1.即true代表1,false代表0。请参考C99头文件<stdbool.h>对bool的定义。
因此Objective-C中的BOOL与C语言中bool是不同的。最大的区别就是两种定义的类型完全不同,一种使char,一种是int。
比如说我可以这样对BOOL、bool赋值
1 |
|
你认为会得到怎样的结果呢?
输出结果是:value1 = 0,value2 = 1;
为什么会这样呢?请继续往下看…
BOOL–不要与YES作比较
YES是Objective-C的真值,与值1相等。BOOL能够拥有从-128到127(包括零)任意一个零值,因此它代表了255种不同的真值。按照惯例,那些函数或者方法总是返回YES或者NO。但是,你不能依赖于它返回的是真值(255种值的任意一个),就说明与YES(它的值为1)就相等。因此与YES(1)想比较是一种不好的想法。像这样:
1 | if ([obj1 has:obj2] == YES) { |
因为没有编译器会执行一个变量或者一个值,总是保持YES或者NO。
也许,你还不是很明白,没关系,我再举一个例子说明,直接与YES比较是不合理的。
1 |
|
或者
1 |
|
然而,你像这样使用方法或者函数,
1 |
|
以上实例,你觉得会得到什么结果呢?会输出 “不相等”吗?。哈哈…,不好意思,编译器会给你开一个玩笑!,最终输出的结果会是这样的
1 |
|
实际上返回值应该是1,-1,-30,0。注意最后一个输出为什么是0。当然,与NO相比较,总是安全的,因为在C语言中只有0代表false,在OC也一样 YES 和 NO。
我们来分析下,512与256相比较为什么是相等,即返回值是0。有这样一段代码:
1 |
|
输出结果是0即NO。我们把256转化成二进制位1 0000 0000。根据BOOL,是一个占8 bits的char类型。因此编译器会剔除高位的数据,保留低8位的数据。在这个1 0000 0000中,保留0000 0000,再转化成10进制为0,0在OC中被定义为NO。而 512 - 256 等于 256。因此会输出相等。我们把上面的代码片段 修改成这样:
1 |
|
输出结果是1即YES。因为 bool 就两个值0和1。
再举一个例子。
1 |
|
这种 返回的 结果是不确定的,有可能是YES,也有可能是NO。假设name的指针是0x010CA683,将返回YES,如果name指针是0x010BA600,将返回NO。
原因也是BOOL类型只会保留8 bits 的数据。为真的时候保留0x83,为假的时候保留0x00。因此你可以这样做:
1 |
|
或者
1 |
|
因此,不要这样写是非常有必要的,千万不要这样写:
1 |
|
或者
1 |
|
但可以这样写
1 |
|
1 |
|
!!注意:以上实例可以建立一个 MAC工程,运行,观测其输出结果。!!
总结
非常感谢你能看完本文文章,所以在使用YES与其他相比较的时候特别的注意,这也是在代码规范中特别要避免的地方。如上面有什么错误,请联系我`woodjobber@outlook.com`。非常感谢!!!
微信公众号:嘀咕嘀咕(iOSSharers)
扫二维码关注
