为什么[@(!var)class]返回' __NSCFNumber而不是'比' __NSCFBoolean&#39 ;?

时间:2018-04-22 04:26:38

标签: ios objective-c clang llvm

当我将字典@{@"MUTE":@(flag)}传递给+[NSJSONSerialization dataWithJSONObject:options:error:]时,它会返回一个类似{ "MUTE" : true }的JSON,这正是我所期望的。

但是当我将字典更改为@{@"MUTE":@(!flag)}时,它会生成一个类似于此{ "MUTE" : 0 }的JSON,这是我们服务器无法接受的。

所以我写了一些测试代码来找出这里发生了什么:

BOOL var = YES;
NSLog(@"%@", [@(var) class]);       // print __NSCFBoolean
NSLog(@"%@", [@(!var) class]);      // print __NSCFNumber
NSLog(@"%@", [@((BOOL)!var) class]);// print __NSCFBoolean

似乎逻辑NOT表达式产生非BOOL类型的值。

但是在用C ++重写代码后,clang告诉我一个不同的故事:

BOOL var = ((bool)1);

NSLog((NSString *)&__NSConstantStringImpl__var_folders_vg_0k7tkth9043fl0g9sf5l9l3w0000gn_T_main_8479d3_mi_0, ((Class (*)(id, SEL))(void *)objc_msgSend)((id)((NSNumber *(*)(Class, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), (BOOL)(var)), sel_registerName("class")));
NSLog((NSString *)&__NSConstantStringImpl__var_folders_vg_0k7tkth9043fl0g9sf5l9l3w0000gn_T_main_8479d3_mi_1, ((Class (*)(id, SEL))(void *)objc_msgSend)((id)((NSNumber *(*)(Class, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), (BOOL)(!var)), sel_registerName("class")));
NSLog((NSString *)&__NSConstantStringImpl__var_folders_vg_0k7tkth9043fl0g9sf5l9l3w0000gn_T_main_8479d3_mi_2, ((Class (*)(id, SEL))(void *)objc_msgSend)((id)((NSNumber *(*)(Class, SEL, BOOL))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithBool:"), ((BOOL)!var)), sel_registerName("class")));

任何人都知道@(!var)中有什么问题?

1 个答案:

答案 0 :(得分:3)

这是Objective-C的C部分。 C逻辑运算符(例如&&||!都将其操作数与(un)等于0进行比较,并返回int值0或1。这源于C最初没有任何内置布尔类型。

因此,在您的表达式@(!var)中,!var的类型为int,并创建了__NSCFNumber个对象。

HTH