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)
扫二维码关注