在处理服务器返回值时,遇到了一下的问题.之后注意到了 BOOL 值不是那么简单的.
先说明一下问题, 下面是服务器返回的JSON 数据:
{
success = 0,
data = <null>,
message = <null>,
errorMessage = 登录名或密码不正确
}
上面的 JSON 我们可以看出 success 是一个 BOOL 值.好那个我做了如下的判断.
if (json[@"success"] == YES) {
NSLog(@"成功");
} else {
NSLog(@"失败");
}
看起来很简单.但是** json[@"success"] == YES**这个判断有一个警告.
比较一个指针和一个 integer. 运行结果是没问题. BOOL 是一个指针??
当我去打印真实类型的时候
NSLog(@"%@", [json[@"success"] class]);
// __NSCFBoolean
__NSCFBoolean这个又是什么东西??
下面做几个测试
#import <Foundation/Foundation.h>
static BOOL different (int a, int b) {
return a - b;
}
int main(int argc, const char * argv[]) {
bool a = YES;
BOOL b = YES;
Boolean c = YES;
NSLog(@"a = %d, b = %hhd, c = %hhu", a, b, c);
// a = 1, b = 1, c = 1
if (different(11, 10) == YES) {
NSLog(@"11 != 10");
} else {
NSLog(@"11 == 10");
}
// 11 != 10
if (different(10, 11) == YES) {
NSLog(@"10 != 11");
} else {
NSLog(@"10 == 11");
}
// 10 == 11
if (different(512, 256) == YES) {
NSLog(@"512 != 256");
} else {
NSLog(@"512 == 256");
}
// 512 == 256
return 0;
}
看到前面默认打印的是1, 觉得还正常,后面完全就乱套了.到底怎么了.
通过进出objc/objc.h 我们看到 对于 BOOL 其实是
**typedef signed char BOOL; **
#define YES ((BOOL)1)
#define NO ((BOOL)0)
所以在 OC 中,当遇到处理真假的参数时,使用BOOL, 字面值是 YES 和 NO.由于signed char只有8位的存储空间,超过8位的只取8位二进制进行判断,所以才看到了.上面判断出错的情况.
所以在 c 中的 bool,0是假值,非0为真值,在 OC 中却不是如此.
下面再看一下__NSCFBoolean.它其实是一个封装好的对象.是NSNumber 类簇中的一个私有的类.
NSLog(@"%@", [@(YES) class]);
NSLog(@"%@", [@(1) class]);
// 结果:
// __NSCFBoolean
// __NSCFNumber
通过下面的图,可以有更好的理解