【问题标题】:Why is BOOL type in Objective-C a char?为什么Objective-C中的BOOL类型是char?
【发布时间】:2012-12-28 22:40:59
【问题描述】:

有人告诉我,Objective-C 中的 BOOL 是无符号字符的 typedef,而 YES 和 NO 关键字是编码字符。这不是我第一次听到。我读过这是因为苹果在 C 标准提供 _Bool 类型之前使用了 BOOL,我错了吗?这个事实有什么好处吗?我们在浪费内存吗?这是否提供了一种在函数中返回有价值数据的方法?当某些意外行为发生时,将其用作返回不同值的方法是否正确?

BOOL myFunction(int argument)
{
    BOOL result = YES; //The function generates the result
    if (someError == YES) {
        return 5;
    }
    return result;
}

【问题讨论】:

标签: ios objective-c boolean


【解决方案1】:

我们是否在浪费内存?

不,因为你不能得到一个小于char 的变量:它总是一个字节。您可以将表示布尔标志的多个位打包在一个单词中,但您必须手动执行 - 使用位移位、使用位域等等。

这是否提供了一种在函数中返回有价值数据的方法?

并非如此:您所做的是 hack,尽管 5 肯定会通过系统到达调用者,并且会在“普通”if 语句中被解释为 YES,例如

if (myFunction(123)) {
    ...
}

但是,如果像这样使用它会惨遭失败:

if (myFunction(123) == YES) { // 5 != YES
    ...
}

当某些意外行为发生时,将其用作返回不同值的方法是否正确?

从可读性的角度来看,它总是不正确的;至于“做你想做的事”,你的里程可能会有所不同,这取决于你的功能的使用方式。

【讨论】:

  • 还不如只返回一个 int 并完成它。感谢您强调可读性方面。维护“聪明”的人的代码是一件痛苦的事
  • 解决问题的方法:if (myFunction(123) == YES)if (!!myFunction(123) == YES)。您偶尔会看到用于将非零数转换为 BOOL YES 值的双重否定。
  • @Zaph 是的 - 这就是真正的防御性程序员保护自己免受喜欢的人的黑客攻击的方式:)
【解决方案2】:

有一点优势:在很多平台上(包括iOS、IIRC),sizeof(_Bool) == sizeof(int),所以使用char可以稍微紧凑一些。

除了BOOL 实际上是signed char,而不是char,所以@encode(BOOL) 在所有平台上的计算结果都是一样的。这会使位域稍微复杂化,因为 BOOL foo:1; 似乎定义了一个 1 位有符号整数(IIRC,其行为未定义)——显然 unsigned char 会是更好的选择,但可能为时已晚。

_Bool 也应该更好地优化,因为编译器可以对所使用的位模式做出假设,例如用a&b 替换a&&b(前提是b 没有副作用)。一些架构还将“真”表示为所有位集,这对于屏蔽很有用(想到 SSE 比较指令)。

【讨论】:

    【解决方案3】:

    “Objective-C 中的BOOL”不是无符号字符,它是Objective-C 库定义的任何字符。哪个是 unsigned char 或 bool,取决于您的编译器设置(32 位或 64 位)。两者的行为不同。用 32 位编译器和 64 位编译器试试这段代码:

    BOOL b = 256;
    if (b) NSLog (@"b is true"); else NSLog (@"b is false");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-03
      • 1970-01-01
      • 1970-01-01
      • 2015-09-06
      • 1970-01-01
      • 1970-01-01
      • 2015-02-08
      • 2010-09-20
      相关资源
      最近更新 更多