【问题标题】:Why do nonzero numbers fail to set a BOOL property to YES?为什么非零数字无法将 BOOL 属性设置为 YES?
【发布时间】:2013-11-23 22:22:31
【问题描述】:

据我了解,在基于 C 的 Objective C 中,所有 BOOL 基本上都是短路(-127 到 128),零是“FALSE”或“NO”的唯一值。但是,当我最近尝试根据位掩码设置按钮的选定值时,它失败了。为什么?

NSInteger bitfield = 127;
NSInteger bitmask = 1 << 6; // 64

myButton.selected = bitfield & bitmask; // selected will remain NO

【问题讨论】:

  • 不是我不相信你,而是我不相信你。虽然如果你这样做会激发更多的信心myButton.selected = !!(bitfield &amp; bitmask);
  • @Havenard C 确实有bool
  • @HotLicks 你为什么不相信他? BOOL 不是 bool,因此它不像真正的布尔值那样工作。
  • GoldenJoe,这样做:NSLog(@"selected is %s", myButton.selected ? "YES" : "NO");。问题可能是selected 的一些消费者反过来(并且有些不恰当地)对它进行&amp;| 操作,而不是使用&amp;&amp;||。 (或者做== YES等)
  • UIControl 有一个实例变量unsigned int selected:1。我的测试表明,为“选定”属性分配一个值只是将最低有效位分配给该位字段。例如,self.myButton.selected = 3; NSLog(@"%d", self.myButton.selected); 打印 1

标签: ios objective-c bitmask


【解决方案1】:

那是因为BOOL 不是bool

BOOL 只是(非bool)整数类型的非标准(Objective-C-specific)typedef(据我所知,它总是signed char,但我可能错了) .因此,它表现为真正的布尔数据类型,而是作为其底层整数类型。因此,如果您将 64 分配给它,它将存储 64(而不是 true1)。因此,始终假定 true 值为 1(即 LSB 集)的操作可能无法识别 64。

相反,如果您将BOOL 替换为真正的C99 布尔类型,即_Boolbool,那么您将遇到预期的行为。即,将任何非零值分配给变量将使其存储true1,无论该值是否真的为1。

【讨论】:

  • 正确。该答案的关键部分是“始终假定真值为 1(即 LSB 集)的操作将无法识别 64”。永远不要评估 BOOL,除非通过比较 0(这是隐含的条件 - if(myBool)myBool ? ... : ...)。
  • @JoshCaswell 是的,没错。
  • 那么这是 OP 代码中的错误(因为您“必须”将 YES 或 NO 分配给 myButton.selected),还是“selected”属性(仅存储大小为 1 的位域中的 LSB,如上所述)?
  • @MartinR 我会说 OP 的代码中有一个错误,但 他的假设却是一个错误。
  • @H2CO3 这不是 Apple 特定的。 BOOL 可以追溯到 Objective-C 的创建,并且可能早于 bool。它是在 ObjC仅仅是一个 C 预处理器扩展 + 运行时创建的。因此,向具有新规则(如强制 YES/NO 值)的编译器添加新类型非常困难(如果不是不可能的话)。而且,是的,它是一个 PITA。修复它是一个更大的 PITA,因为总是有重要的代码库会破坏,并且在编译器被修订时没有资源/时间来修复。
猜你喜欢
  • 2011-09-24
  • 2014-12-18
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
  • 1970-01-01
  • 2015-11-24
  • 2010-12-03
  • 1970-01-01
相关资源
最近更新 更多