【问题标题】:Why does the unary bit inversion operator not invert the value of a BOOL?为什么一元位反转运算符不反转 BOOL 的值?
【发布时间】:2014-06-03 16:25:24
【问题描述】:

我想在每次检测到点击时反转 BOOL 的值。 BOOL 的默认值为NO,当我第一次点击它时,它会反转为YES。在随后的点击中,该值保持为YES

@property(nonatomic, assign) BOOL isDayOrNight; //property in timeDayChart object.

self.timeDayChart.isDayOrNight = ~self.timeDayChart.isDayOrNight; //This is done in a VC. 

我不得不把它改成这样:

self.timeDayChart.isDayOrNight = !self.timeDayChart.isDayOrNight;

达到我想要的结果。我想知道为什么~ 没有按预期工作。

【问题讨论】:

  • 请注意~someValallOnesVal - someVal基本相同。

标签: objective-c boolean bit-manipulation


【解决方案1】:

BOOL 在 objc.h 中被定义为有符号字符:

typedef signed char     BOOL; 

YES 和 NO 的定义如下:

#define YES             (BOOL)1
#define NO              (BOOL)0

所以~YES是-2,和NO不一样。

【讨论】:

  • 事实上,~NO 是 -1,虽然它的行为类似于 YES,但它并不是 YES 的规范值。
  • 很好,通过回答。 (已投票)这个答案的简短形式是“因为 '~' 是按位运算符,而不是逻辑否定运算符,所以它不是 *SUPPOSED TO 进行逻辑否定。”
  • 非常感谢大家。
  • @DuncanC - 是的,请记住按位运算符不合逻辑。 ;)
【解决方案2】:

在 (Objective-)C(++) 中,当需要布尔值时,例如在 if 中或作为 && 的操作数时,实际上取整数值并将 0 解释为 false 和非零作为真实。逻辑、关系和相等运算符也都返回整数,使用 0 表示假,1 表示真。

Objective-C的BOOLsigned char的同义词,是一个整数类型,而NOYES分别定义为0和1。

正如您正确指出的那样,~ 是位反转运算符。如果您反转任何包含 0 和 1 的整数,结果也会如此。任何包含 1 位的值都被视为真,并且将除全 1 之外的任何此类值取反会产生一个具有至少一个 1 位的值,该值也被解释为真。

如果你从全 0 开始,那么重复反转应该是全 1、全 0、全 1 - 这是真、假、真等(但 不是是、否、是等。 )。因此,如果您从 0 开始,那么要么您并不总是使用反转,要么您正在显式测试 YES 而不是 true。

但是,正如您所想,您应该使用的是 ! - 逻辑否定 - 它将 0 映射到 1,将非 0 映射到 0,因此可以正确处理 1 以外的“真”值。

HTH

【讨论】:

    【解决方案3】:

    找一本关于 C 语言的书。检查它对 ~ 运算符和 ! 的说明。操作员。 ~ 反转整数中的所有位,BOOL 定义为整数类型。所以 NO = 所有位为零将更改为所有位设置,这与 YES 不同,并且 YES = 除最后一位 = 1 之外的所有位为零将更改为除了最后一位 = 0 之外的所有位设置。

    【讨论】:

      【解决方案4】:

      你最好使用这个习惯用法来切换一个 BOOL 值:

      self.timeDayChart.isDay = self.timeDayChart.isDay ? NO : YES;
      

      (我特意改了你属性的命名)

      【讨论】:

      • 使用 ! 非常适合切换 BOOL。
      • 它是完美的,因为 NOT 运算符为任何非零值返回 1,并且 1 恰好等于 YES。如果YES 不等于1,NOT 运算符就不是完美的,IMO ;) 这避免了在做这样的事情时常见的陷阱:if (x == YES) { ... } 和 x 恰好是 0xFF 或类似的东西。
      • YES 是什么并不重要。无论如何,它必须像 C bool 值一样做出反应,否则 if 语句等将不起作用。
      • C 中的布尔表达式总是计算为 0 或 1。因此,您可以将布尔表达式分配给 BOOL,它等于 YESNO。但只是因为YES 等于 1。所以这很重要。 ;)
      • 普遍的事实是,C-ish 语言中的布尔值应该为零表示 FALSE,非零表示 TRUE。如果 Objective-C 的实现违反了它所有的东西都会破坏。否则,在大多数情况下,YES/TRUE/true 是什么并不重要。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-28
      • 2015-11-23
      • 2014-12-30
      • 2021-12-08
      • 2022-07-20
      相关资源
      最近更新 更多