【问题标题】:When does Objective-C implicitly cast to BOOL?Objective-C 何时隐式转换为 BOOL?
【发布时间】:2013-01-25 20:24:01
【问题描述】:

我读过Mike Ash's Objective-C pitfalls page,现在我对将id 类型的变量隐式转换为BOOL 感到偏执。

假设我有一个低位清零的“危险”指针,因此将其转换为BOOL 会产生NO,即使它指向一个有效对象。让我们称之为“危险”指针foo

简单的 if 语句如何工作? if 语句在评估条件时是否将foo 转换为BOOL?还是转换为纯布尔值?

if( foo )
{
  [myArray addObject:foo];
}

在三元表达式中的工作方式是否相同?

// Does this break when foo is 'dangerous'?
self.titleLabel.hidden = foo ? YES : NO ; 

如果我这样做,三元组是否会中断:

// I'm pretty sure it breaks now
self.titleLabel.hidden = ((BOOL)foo) ? YES : NO ; 

我觉得我缺少一些关于 C 中逻辑运算的基本知识,以及它们与BOOL 的关系。请帮我解惑。

【问题讨论】:

  • 我很确定if ( foo ) 等同于if ( foo != 0 ),它不会将foo 转换为布尔值... cf。 stackoverflow.com/a/6177766/210171
  • 我相信第二个选项也不错,因为同样是(foo != 0) ? YES : NO

标签: objective-c boolean type-conversion


【解决方案1】:

Objective-C 何时隐式转换为 BOOL?

从不,因为这个短语在语义上是不正确的。根据定义,演员表是显式的。您要问的是所谓的“隐式类型转换”(强制 - 谢谢,乔希!)。

此外,严格来说,Objective-C 中的条件并不特殊:它们继承自 C。因此,当需要将表达式作为布尔值进行评估时,不会将其视为 BOOL,而是视为 int

// Does this break when foo is 'dangerous'?`
self.titleLabel.hidden = foo ? YES : NO;

不,它没有。 (expr) 用作“布尔”表达式时,等效于 (expr != 0)。这里没有风险。

// I'm pretty sure it breaks now
self.titleLabel.hidden = ((BOOL)foo) ? YES : NO;

现在这可能会中断,因为 BOOL 只是类型化为 signed char,在 iOS 上是 8 位。因此,如果foo,它是一个(32 位)指针,被截断为 8 位,并且指针的低 8 位全为零,但指针本身不是nil,这将错误地报告错误的。你不想做这种多余的、丑陋的和危险的演员阵容。如果你想更明确,写

var = (obj != nil) ? valueOne : valueTwo;

改为。

【讨论】:

    【解决方案2】:

    您的前两个样本中没有演员表。写 if(expr) 等于写 if(expr == 0)。

    如您参考的文章中所述,您的第三个示例在某些情况下确实可能会中断。

    【讨论】:

      猜你喜欢
      • 2010-12-12
      • 2017-07-17
      • 2015-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      相关资源
      最近更新 更多