声明中的指针总是设置为nil吗?

bac*_*car 13 objective-c

我发现了各种各样的人/文章(例如这个SO答案),表明Objective-C中指针的值在你给它分配之前没有定义.但是,我在实践中发现它们nil在我调用之前自动设置为alloc- 以下代码在没有断言的情况下为我运行:

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
Run Code Online (Sandbox Code Playgroud)

可以/我应该依靠这个吗?是保证还是我恰好在某种调试模式下运行我的编译器(Xcode)?(我是Objective-C的新手).

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

Lil*_*ard 29

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


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

  • 请注意,这仅适用于本地非静态变量.对象类型*的全局,静态和实例变量将根据标准初始化为nil. (7认同)

jus*_*tin 6

(对于ARC,请参阅Kevin的回答)

可以/我应该依靠这个吗?

不 - 从不依赖于此.堆栈内存通常在调试版本中归零(取决于您的编译器设置).启用优化后,编译器不会为您执行此操作,并且您将根据最后堆栈区域中发生的任何事情给出垃圾值.

可以在对象的初始值设定项中依赖归零的ivars.

您可以使用静态分析器保护自己,并-Wuninitialized在优化级别大于时启用构建配置-O0.

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

  1. 未初始化
  2. 已分配但尚未初始化的objc实例(否则不安全)
  3. 初始化的objc实例或对象.