根据Mike Ash的博客文章,由于指针大于BOOL,因此转换为BOOL可能会失败6%。因此,他建议,如果你正在检查一个对象是否存在,你应该检查零。
if (self != nil) {
而不是苹果模板做什么
if (self) {
Apple 的模板是否包含错误,或者是否有其他我不知道的语法糖?
因为他们投射到 BOOL
不,他们没有。根本没有演员表演。但是,存在将表达式作为逻辑值的计算。在指针(nil
和self
)的情况下,NULL
指针的计算结果为 false,其他任何指针的计算结果为 true。这不是一个错误,只是一个速记方法,它是完全有效的C。
关于为什么人们可能想要对NULL
或nil
进行明确的比较:在某些情况下,它可能更具可读性,特别是如果乍一看表达式的类型和范围并不明显。然而,在 Objective-C 和 Cocoa 中,这样做在构造函数中是一个很常见的习惯用法,任何有经验的程序员都会毫无问题地掌握它。
Objective-C 基于 C,而在 C 中,if
语句确实不对布尔值进行操作,也许令人惊讶。
C 具有以下类型的层次结构:
char
、整数和枚举(enum
)类型是整数类型float
、double
和long double
是真正的浮动类型- 有三种复数类型,与实际浮点类型一起简称为浮点型
- 整数类型和浮点类型组合形成算术类型
- 算术类型与指针类型一起构成标量类型
唷!
现在到if
语句,它的形式之一:
if ( expression ) statement
if ( expression ) statement else statement
其中表达式必须是任何标量类型。如果表达式比较不等于 0,则执行第一个(或唯一)语句,如果表达式比较等于 0,则执行第二个(如果存在)语句。
所以:
if (self) ...
和
if (self != nil) ...
结果相同。
第一个表达式self
是某种指针类型,它是一种标量类型,并因不等于指针类型的零(在代码中用nil
表示)进行比较。第二个表达式self != nil
是一个相等表达式,产生int
类型的0
或1
,这也是一个标量类型...
因此,从技术上讲,第二种形式涉及int
值的中间生成,但没有编译器会实际生成一个(当然,除非您将表达式的结果分配给变量)。
笔记:
- 有点奇怪的
if ( sin( angle ) ) ...
是有效的... switch
语句对整数类型而不是标量类型进行操作
呵呵
不,如果指针不为 nil,这不会失败,它是安全的,唯一的区别是语法,我不推荐一种或另一种方式,因为它们是相同的。 你不是在将 self 转换为 bool,你只是在检查 self 是否与零不同。
已编辑
根据马丁的评论,我记录了错误的调试消息。 是一样的
这是一个简单的测试
NSString *str = nil;
// suppose our string points to a string object whose starting address is 0x4500
//I'm assigning it manually so that I can test
str = 0x4500;
NSLog(@"%d",str);
if (str) {
NSLog(@"It's non-nil");
}
else {
NSLog(@"It's nil");
}
if (str == nil) {
NSLog(@"It's nil");
}
else {
NSLog(@"It's non-nil");
}
输出为 :
It's non-nil
It's non-nil