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

时间:2013-01-25 20:24:02

标签: objective-c boolean type-conversion

我读了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的关系。请帮助赐教。

2 个答案:

答案 0 :(得分:8)

  

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

从不,因为这个短语在语义上是不正确的。根据定义,演员是明确的。您所询问的内容称为“隐式转换”(强制 - 谢谢,Josh!)。

另外,严格地说,Objective-C中的条件并不特殊:它们是从C继承的。因此,当需要评估为布尔值时,表达式不会被视为BOOL,而是int。 1}}。

// 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位。因此,如果{(1)}(一个(32位)指针)被截断为8位,并且指针的低8位全部为零,但指针本身不是foo,这将错误地报告错误。你不想做这个多余,丑陋和危险的演员。如果你想更明确,请写

nil

代替。

答案 1 :(得分:1)

前两个样本中没有投射。写if(expr)等于写if(expr == 0)。

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