3

我阅读了Mike Ash 的 Objective-C 陷阱页面,现在我对隐式类型的变量转换idBOOL.

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

简单的 if 语句如何工作?if 语句在评估条件时是否foo转换为 a ?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. 请帮我解惑。

4

2 回答 2

8

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;

反而。

于 2013-01-25T20:30:09.837 回答
1

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

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

于 2013-01-25T20:31:47.747 回答