本节书摘来自华章出版社《编写高质量代码:改善Objective-C程序的61个建议》一 书中的第2章,作者:刘一道,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
建议16:明智而审慎地使用BOOL类型
整型转换为BOOL 型时,要小心,不要直接和YES作比较。
BOOL 在Objective-C里被定义为unsigned char,这意味着它不仅仅只有YES(1)和NO(0)两个值。不要直接把整型强制转换为BOOL 型。常见的错误发生在把数组大小、指针的值或者逻辑位运算的结果赋值到BOOL型中,而这样就导致BOOL 值仅取决于之前整型值的最后一个字节,有可能出现整型值不为0但被转为NO的情况。因此把整型转为BOOL型的时候请使用三元(Ternery)操作符,保证返回YES 或NO 值。
在BOOL、_BOOL 及bool(见C++ Std 4.7.4、4.12及C99 Std 6.3.1.2)之间可以安全地交换值或转型。但BOOL 和Boolean 之间不可以,所以对待Boolean 就像上面讲的整型一样就可以了。在Objective-C函数签名里仅使用BOOL 。
对BOOL值使用逻辑运算(&&, ||, !)都是有效的,返回值也可以安全地转为BOOL型而不需要三元(Ternery)操作符。
// AVOID
- (BOOL)isBold {
return [self fontTraits] & NSFontBoldTrait;
}
- (BOOL)isValid {
return [self stringValue];
}
// GOOD
- (BOOL)isBold {
return ([self fontTraits] & NSFontBoldTrait) ? YES : NO;
}
- (BOOL)isValid {
return [self stringValue] != nil;
}
- (BOOL)isEnabled {
return [self isValid] && [self isBold];
}
还有,不要把BOOL 型变量直接与YES 比较。这样不仅对于精通C的人很有难度,而且此条款的第一点也说明了这样做未必能得到你想要的结果。
// AVOID
BOOL great = [foo isGreat];
if (great == YES)
// ...be great!
// GOOD
BOOL great = [foo isGreat];
if (great)
// ...be great!
要点
(1)整型转为BOOL型,使用三元(Ternery)操作符,以保证返回YES 或NO 值。
(2)整型转换为BOOL型的时候要避免直接和YES做比较。
(3)BOOL值进行逻辑运算(&&, ||, ! )不但有效,而且还可以确保返回值安全地转为BOOL型,无须三元(Ternery)操作符。