int值不“适合”的含义 - 用于Objective-C的bool或BOOL?

6

在这里的注释 -- https://dev59.com/EGox5IYBdhLWcg3wKBN9#9393138 -- 我发现当用一个int值来设置BOOL的值时,它会有一些意想不到的行为。大多数情况下,如果将该值设置为0x1000,它将被评估为FALSE(令人惊讶)。

NSLog(@"All zero? %d %d", (BOOL)0, (bool)0);
NSLog(@"All one? %d %d %d", (BOOL)4095, (BOOL)4096, (BOOL)4097); // 4096=0x1000 or 8-bits
NSLog(@"All one? %d %d %d", (bool)4095, (bool)4096, (bool)4097);

Produces:
All zero? 0 0
All one? -1 0 1
All one? 1 1 1

我认为这很奇怪,但我很少将int转换为BOOL。然而:
  1. 这是否意味着应该优先使用bool而不是BOOL?为什么?
  2. 可以使用

if (thatBool) {

还是应该使用

if (thatBool ? YES : NO) {

为什么?

注意:这是这个问题的一个更具体的版本--Objective-C : BOOL vs bool--但我认为它增加了问题的深度,不是重复的。

3个回答

3

我认为(BOOL)4096被计算为0是一个简单的算术溢出,就像(BOOL)256一样,因为BOOL是一个unsigned char。而且我认为!!转换技巧(“双重否定”)很好地工作:

NSLog(@"%i", (BOOL)256); // 0
NSLog(@"%i", !!256); // 1

这意味着我将使用BOOL来保持标准的Cocoa编码风格,只需注意危险的类型转换即可。 thatBool ? YES : NO表达式让人不舒服,为什么要这样做? :)


!! 强制类型转换技巧的任何链接?这些东西有点难以搜索 :) - Dan Rosenstark
这是一个简单的双重否定,应该更容易搜索。 - zoul
谢谢@zoul,是的,那很容易。我认为“注意危险类型转换”是正确的。 - Dan Rosenstark

2

1) bool是C++的类型,BOOL是Objective-C的类型。从int强制转换为BOOL无法正常工作,因为YES只是(BOOL)1 = (signed char)1(= 0x001),而这与(signed char)4(= 0x100)不相等,例如。

2) 两种方式都可以,但对于编程经验较少的人来说,第二种可能难以理解。我更喜欢使用旧式的C语言安全条件检查,将常量置于左侧以防止意外省略一个等号。

if (YES == isEnabled) {

}

2
只是补充一下,“if (thatBool ? YES : NO) {”是无用的,它只是一个if中的if(ifception!),这是相同的事情。 - fbernardo
1
我喜欢Yoda风格,我总是想象程序员真的像这样说话,太有趣了 :) - JustSid
而且它非常实用,实际上是这样的 :-D - Alexander
1
我发现反转操作数的 == 实在令人不安 :) 而且最重要的是,我认为这已经不再需要了,因为现代编译器会警告你关于 if (foo = YES) 赋值的问题。 - zoul
2
在这种情况下,bool 是来自 C99 而不是 C++。 - jscs
显示剩余3条评论

0

在使用 int 时,您可以通过检查 int 是否等于特定值来显式设置 BOOL,例如:

BOOL yesNo = ((int)4096 > 0);
BOOL enableButton = (someInt >= 16);

换句话说,不要直接将 int 传递给 BOOL;而是将其转换为真/假语句。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接