【问题标题】:Objective-C unallocated pointerObjective-C 未分配指针
【发布时间】:2011-02-05 01:55:02
【问题描述】:

我对 Objective-C 中的 nil 感到困惑,因为苹果说可以向 nil 对象发送消息。

所以假设这段代码:

Foo * myFoo;
[myFoo doSomeStuff];

在 Xcode 中这不会崩溃,为什么?在 Objective-C 中未分配的指针是否与 nil 相同。

谢谢。

【问题讨论】:

  • myFoo 是全局变量吗?这些总是初始化为零。
  • myFoo 不是全局变量。
  • @Gallois:未分配的指针和未初始化的指针是有区别的。您有一个未初始化的指针,当指针在堆栈(局部变量)上分配且未初始化时,行为未定义,如答案中所述。

标签: objective-c pointers null


【解决方案1】:

因为nilrandom garbage 之间存在差异。你看,这一行:

Foo * myFoo;

如果您没有明确设置myFoo 的值,则不做任何保证。自己试试吧:

Foo* myFoo;
printf("%x\n", myFoo);

很可能不会打印0;相反,它将打印发生在该内存位置的最后一件事。 (它可能为零。但很可能不是。)

在你自己赋值之前,局部变量有一个未定义的值。 Objective-C 运行时将允许调用 nil 工作,但 nil 被严格定义为零:因此,您必须将变量初始化为 nil 才能使用此功能(否则,您可能会得到分段错误,因为消息传递随机地址对您的程序不利)。

这将始终“工作”(“工作”我的意思是不会崩溃):

Foo* myFoo = nil;
[myFoo whatever];

这是一个示例程序,在我的机器上,始终没有零指针:

#include <stdio.h>
#include <string.h>

struct random_stuff
{
    int stuff[60];
};

struct random_stuff scramble()
{
    int filler = 0xdeadbeef;
    struct random_stuff foo;

    memset_pattern4(&foo.stuff, &filler, sizeof foo);
    return foo;
}

void print()
{
    void* pointer[30];
    for (int i = 0; i < 30; i++)
        printf("%p\n", pointer[i]);
}

int main()
{
    scramble();
    print();
}

【讨论】:

  • @Gallois 在一个非常简单的程序(只是 main 方法)中,它很可能会打印 0。我将更新一个不打印 0 的示例。
  • 我明白谢谢,但我的问题是这不会崩溃。似乎Objective-C将未分配的指针视为与nil相同!!!
  • @Gallois 哦,我把你的问题弄错了。好吧,未分配的指针有可能获得nil 值,但这确实是机会。如果你这样做:Foo* myFoo = (Foo*)0xdeadbeef; 你会发现向任何地方发送消息都行不通。
  • 谢谢,我现在明白了:)。
【解决方案2】:

这取决于变量。实例变量、全局变量或静态变量将被初始化为零,除非您将其初始化为其他值。一个普通的局部变量没有被初始化为任何定义的值,并且像这样发送一个变量通常会崩溃。请注意,这是通常,而不是总是——当您谈论未定义的行为时,几乎任何事情都是可能的,包括崩溃、发送到错误对象的消息或大多数时候似乎是正确的,但随机失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 2011-09-26
    相关资源
    最近更新 更多