9

根据Mike Ash 的博客文章,由于指针大于 BOOL,因此转换为 BOOL 的概率为 6%。正因为如此,他建议如果你正在检查一个对象是否存在,你应该检查 nil

if (self != nil) {

而不是 Apple 模板所做的是

if (self) {

Apple 的模板是否包含错误或是否有其他一些我不知道的语法糖?

4

4 回答 4

12

因为他们转换为 BOOL

不,他们没有。根本没有演员表演。然而,有一个表达式的评估作为一个逻辑值。在指针(whichnilselfare)的情况下,NULL指针的计算结果为 false,其他任何结果为 true。这不是错误,只是一种简写方式,它是完全有效的 C.

关于为什么要对NULLor进行显式比较nil:在某些情况下,它可能更具可读性,特别是如果乍一看表达式的类型和范围并不明显。但是,在 Objective-C 和 Cocoa 中,在构造函数中执行此操作非常常见,任何有经验的程序员都会毫无问题地掌握它。

于 2012-12-17T14:41:43.900 回答
4

Objective-C 是基于 C 的,而在 C 中,if语句确实,也许令人惊讶的是,不对布尔值进行操作。

C 有一个类型的层次结构:

  • char整数和枚举 ( enum) 类型是整数类型
  • float和是真正的double浮动类型long double
  • 存在三种复数类型,与实浮点类型一起简称为浮点类型
  • 整数类型和浮点类型组合形成算术类型
  • 算术类型和指针类型形成标量类型

呸!

现在到if声明,它是以下形式之一:

if ( expression ) statement
if ( expression ) statement else statement

where表达式必须是任何标量类型。如果表达式比较不等于 0,则执行第一个(或唯一)语句,如果表达式比较等于 0,则执行第二个(如果存在)语句

所以:

if (self) ...

if (self != nil) ...

结果相同。

第一个表达式self是一些指针类型,它是一个标量类型,并且被比较为不等于指针类型的零(在代码中由 表示nil)。第二个表达式self != nil是一个等式表达式,并产生一个01类型int,它也是一个标量类型......

所以从技术上讲,第二种形式涉及一个int值的中间产生,但没有编译器实际上会产生一个(当然,除非你将表达式的结果分配给一个变量)。

笔记:

  1. 有点奇怪if ( sin( angle ) ) ...是有效的......
  2. switch语句对整数类型而不是标量类型进行操作

高温高压

于 2012-12-17T17:40:17.623 回答
3

不,如果指针不为零,这不会失败,它是安全的,唯一的区别是语法,我不会推荐一种或另一种方式,因为它们是相同的。您没有将 self 转换为 BOOL,您只是在检查 self 是否不同于零。

于 2012-12-17T14:43:33.140 回答
2

已编辑
根据 Martin 的评论,我记录了错误的调试消息。一样的

这是一个简单的测试

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
于 2012-12-17T15:17:56.217 回答