我读了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
的关系。请帮助赐教。
答案 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)。
在某些情况下,您的第三个示例可能确实会中断,如您所引用的文章所述。