Objective c 指针在声明时是否总是设置为零?

Objective c 指针在声明时是否总是设置为零?,objective-c,Objective C,我发现各种各样的人/文章(例如)都在暗示,Objective-C中指针的值在您分配给它之前是没有定义的。然而,我在实践中发现,即使在我调用alloc之前,它们也会自动设置为nil——下面的代码为我运行,没有断言: NSString* foo; // 1 assert(foo==nil); // foo is nil foo = [NSString alloc]; // 2 assert(foo!=nil); // after alloc, not nil

我发现各种各样的人/文章(例如)都在暗示,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
的正确术语是什么?我想1和2中至少有一个被称为“未初始化”,2和3中的一个被称为“初始化”,但第三个选项是什么,我们称之为什么?

(有关ARC,请参阅Lily Ballard的)

我可以/应该相信这一点吗

不,永远不要依赖它。堆栈内存通常在调试版本中归零(取决于编译器设置)。启用优化后,编译器不会为您执行此操作,并且会根据堆栈区域上发生的任何情况为您提供垃圾值

您可以依赖对象的初始值设定项中的零IVAR

当优化级别大于
-O0
时,您可以使用静态分析器并通过为构建配置启用
-Wuninitialized
来保护自己不受此影响

一个推论问题:在标记为1、2和3的行末尾,描述处于状态的foo的正确术语是什么?我想1和2中至少有一个被称为“未初始化”,2和3中的一个被称为“初始化”,但第三个选项是什么,我们称之为什么

  • 未初始化
  • 已分配但尚未初始化的objc实例(否则使用不安全)
  • 初始化的objc实例或对象
  • 在下,初始化时所有对象指针都设置为
    nil
    。当不在ARC下运行或使用指向其他数据类型的指针时,未初始化的指针将有一个垃圾值(事实上,根据C标准,从指针读取会产生未定义的行为)



    @Chuck指出了一件重要的事情,那就是这只适用于局部变量。任何具有静态存储(函数静态或全局)的变量和实例变量始终初始化为各自的零值(对于指针而言,零值为
    nil
    /
    NULL
    )。

    对推论问题的回答:

    在#1之后,foo已声明,但未初始化

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

    在#3之后,foo已经初始化

    实际上,您永远不希望将步骤2和步骤3分开,也就是说,您的代码应该是
    foo=[[NSString alloc]init]
    。这样做的原因是,分配一个对象而不初始化它或不正确地初始化它是“危险的”


    如果您只是这样做
    foo=[NSString alloc]
    ,但忘记调用init,那么使用foo是不安全的,因为它尚未初始化。同样,这样做同样不安全(注意没有重新分配给foo),因为init可以返回一个与alloc最初分配的不同的对初始化对象的引用。

    在ARC环境中,对象会自动设置为nil。但在初始化过程中为对象赋值总是一个好的做法

    我刚刚在ARC环境下用obj-c做了一个测试

    NSString *testStr ;
    if (testStr == nil) {
        NSLog(@"Test Successful");
    }
    
    输出:
    测试成功

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

    输出:
    alloc对象初始化后测试成功

    ,通常不==nil。等于nil。注意,这只适用于局部非静态变量。根据标准,对象类型的全局变量、静态变量和实例变量将被初始化为零。@Chuck:很好。我会相应地更新我的答案。你能链接到说明这一点的文档吗?我以为ARC链接会有它,但它似乎没有(我在页面上搜索了‘nil’)@bacar:参见我在回答中链接的文档的第4.2节。具体地说,从初始化开始的位。如果我能弄清楚如何禁用断言,我会尝试打开它们,然后发回-只是为了检查它是否也禁用断言?@bacar:禁用断言是通过
    NS\u BLOCK\u assertions
    编译器宏来完成的。是否存在指针自动为零的情况?如果没有,这就减轻了我对向nil发送消息的大部分担忧…@bacar程序的静态内存和对象的ivar在初始化时将为
    nil
    。您可以使用我在(扩展的)回答中提到的诊断来定位这些病例。这个术语是否记录在某个地方,或者在一本书中,或者仅仅是你在社区中观察到的东西?这是标准的计算机科学术语。好吧:-)我来自一个C++/C的背景,在这个背景下,对象要么是构造的,要么不是-没有“介于两者之间”。实际上,只要你遵循我在回答中指出的规则,Objective-C对象也是如此。
    NSString *testStr = nil;
    if (testStr == nil) {
        NSLog(@"Test Successful");
    }