2012-01-30 132 views
12

我发现了各种各样的人/文章(例如this SO answer),它们表明Objective-C中指针的值在您为其指定某些内容之前未定义。但是,我发现在实践中,他们将自动设置为我叫alloc甚至在nil - 下面的代码我运行,而无需断言:指针是否始终设置为零?

NSString* foo;   // 1 
assert(foo==nil);  // foo is nil 
foo = [NSString alloc]; // 2 
assert(foo!=nil);  // after alloc, not nil. 
foo = [foo init];  // 3 
assert(foo!=nil);  // still not nil 

可以/我应该靠这个?它是保证还是只是碰巧在某种调试模式下运行我的编译器(Xcode)? (我是Objective-C的新手)。

一个必然的问题:在标记为1,2和3的行末尾描述foo的正确术语是什么?我想至少有一个被称为'未初始化',并且其中一个'已初始化',但是其中,我们称之为第三个选项?

+0

页头对象之后进行初始化,通常不==零。等于零它是错误 – theWalker 2012-01-30 22:52:34

+1

可能的重复http://stackoverflow.com/questions/3989377/xcode-compiler-doesnt-set-my-variable-and-pointer-initial-value-to-0-or-nil – 2012-01-30 22:54:35

回答

25

ARC,所有对象指针在初始化设置为nil。当不在ARC下运行时,或者在使用指向其他数据类型的指针时,未初始化的指针将具有垃圾值(实际上,根据C标准,从指针读取会产生未定义的行为)。


@Chuck指出了一些重要的东西,这就是说这只适用于局部变量。任何具有静态存储(函数静态或全局变量)和实例变量的变量总是被初始化为它们各自的零值(对于指针,其值为nil/NULL)。

+7

请注意,这只适用于局部非静态变量。根据标准,对象类型*的全局,静态和实例变量将被初始化为零。 – Chuck 2012-01-30 22:54:27

+0

@Chuck:非常好的一点。我会相应地更新我的答案。 – 2012-01-30 22:55:14

+0

你能链接到说明这个请求的文档吗?我认为ARC链接会有它,但它似乎并不(我在页面搜索'零') – bacar 2012-01-30 23:24:07

6

(电弧,看凯文的答案)

可以/我应该靠这个?

不是 - 永远不要依赖那个。堆栈内存通常在调试版本中归零(取决于您的编译器设置)。启用优化后,编译器不会为您执行此操作,并且会根据堆栈区域上最后存在的任何内容给出垃圾值。

可以依靠归零ivars在你的对象的初始化。

您可以使用静态分析器来防止自己陷入困境,并且在优化级别大于-O0时为您的构建配置启用-Wuninitialized

一个必然的问题:在标记为1,2和3的行的末尾描述foo的正确术语是什么?我想至少有一个被称为'未初始化',并且其中一个'已初始化',但是其中,我们称之为第三个选项?

  1. 未初始化
  2. 已分配,但尚未初始化(不可靠的,否则使用)
  3. 初始化的objc实例或对象的objc实例。
+0

I如果我能弄明白,那么就试着打开它们,然后发回 - 只是为了检查,它是否也会禁用断言? – bacar 2012-01-30 22:56:03

+0

@bacar:禁用断言是通过'NS_BLOCK_ASSERTIONS'编译器宏完成的。 – 2012-01-30 22:57:15

+0

是否曾经有过一个指针自动为零的情况?如果没有,这减轻了我关于发送消息到零的大多数顾虑... – bacar 2012-01-30 23:00:02

1

的回答你的推论问题:

后#1,富一直宣布初始化

经过#2之后,foo已被分配为但仍未未初始化

在#3之后,foo已被初始化为

在实践中,你永远不想分开第2步和第3步,那就是你的代码应该是foo = [[NSString alloc] init]。原因在于分配对象并不初始化或不正确地初始化对象是“危险”的。

如果你只是做这个foo = [NSString alloc]但忘记永远调用init,使用foo是不安全的,因为它没有被初始化。同样,这样做[foo init](注意缺少重新分配给foo)也是不安全的,因为init可以返回与最初由alloc分配的初始化对象不同的引用。

+0

这个术语是记录在某个地方,或是一本书里,或者只是你在社区中观察到的东西? – bacar 2012-01-30 23:24:58

+0

这是标准的计算机科学术语。 – UIAdam 2012-01-30 23:25:52

+0

好的:-)我来自一个C++/C#背景,其中的对象或者是构造的,或者是不是 - 不在中间。 – bacar 2012-01-31 00:17:58

0

在ARC环境中,对象自动设置为零。但是在初始化过程中为对象赋值时总是一个好习惯。

我只是跑与OBJ-C测试中ARC环境

NSString *testStr ; 
if (testStr == nil) { 
    NSLog(@"Test Successful"); 
} 

OutPut :测试成功

NSString *testStr = nil; 
if (testStr == nil) { 
    NSLog(@"Test Successful"); 
} 

OutPut :测试成功