【问题标题】:Asterisk usage in Objective-C: related questionsObjective-C 中的星号用法:相关问题
【发布时间】:2011-01-04 12:08:29
【问题描述】:

我有几个与此相关的问题:Asterisk usage in Objective-C

NSArray 数组;在本地范围内将是堆栈上“分配”的对象。 NSArray *数组;表示由一大块内存支持的对象,通常从堆中分配。

你怎么知道什么时候在栈和堆上分配了东西?都是栈上的局部变量,都是堆上的指针吗?

因为您没有取消引用指向对象的指针,并且指向对象的指针在方法实现本身中至关重要。当你说...

【问题讨论】:

    标签: objective-c cocoa objective-c-runtime


    【解决方案1】:

    你怎么知道什么时候在栈和堆上分配了东西?是不是所有的局部变量都在栈上……

    没关系。栈和堆是实现细节; C 和 Objective-C 语言不知道它们,您通常不应该有任何理由关心某些东西是在堆栈上还是在堆上。

    在 Mac OS X 上,局部变量在堆栈中。但是,对于几乎所有目的,这都无关紧要。不用担心。

    ……所有的指针都在堆上吗?

    没有。指针是内存地址;就是这样。

    指针变量可以是任何其他变量可以的任何地方,也就是说,任何地方(受您不需要关心的实现定义的限制,如上所述)。

    更多信息请参见my pointer tutorial

    因为您没有取消引用指向对象的指针,并且指向对象的指针在方法实现本身中至关重要。当你说...

    指针是内存地址。因此,它指的是该地址处的内存。取消引用指针正在访问该内存。

    您永远不会直接访问 Cocoa 对象占用的内存。你只给它发送消息,要么问它问题,要么告诉它做事。因此,您永远不会取消引用指针。

    “……指向对象的指针在方法实现本身中至关重要。”意味着对象在其方法实现中将需要自己的指针。只能向指向对象的指针发送消息(此细节通常被省略)。如果您以某种方式将其取消,则消息的接收者(即您发送消息的对象)将没有自己的指针。

    假设可以向取消引用的对象发送消息。规范仍然是向指向对象的指针发送消息,因此对象很可能仍然需要指向自身的指针——这使得向取消引用的对象发送消息的假设能力毫无用处。

    由于它没用,他们完全忽略了它。该对象将需要自己的指针(该指针对对象的方法实现至关重要),因此您可以向其指针发送消息。

    【讨论】:

    • 感谢彼得的精彩解释。您应该是老师或其他人:P 所以说以下是否正确: 1)正如 bbum 所提到的,Objective-C 不支持堆栈上的变量。当您调用 alloc 时,它只是调用 malloc,这意味着您必须拥有指向它的指针,因为它只是返回一块内存。 2) 每个 Objective-C 方法都需要一个指向对象的指针。这就是它的实现方式。
    • 1.这不是bbum所说的。他说Objective-C 不支持堆栈上的Objective-C 对象,这是真的。变量可以在堆栈上(如果堆栈存在,它在当前的 Mac OS X 中是这样的)。 alloc 所做的,比“为一个对象分配内存并返回指向它的指针”更具体,是一个实现细节。 2. 这不是“只是如何实现”,而是唯一有意义的方式。没有自己的指针,对象不能对自己做任何事情,所以没有理由你可以在没有指针的情况下向对象发送消息。
    • 所以我想我的下一个问题是:为什么一个对象需要自己的指针?
    • 向自己发送消息(因为您只能向指针发送消息)并访问自己的实例变量。
    • 详细说明:为了让一个对象向自己发送消息,它必须有self,它是一个指针。没有它,它就无法向自己发送消息。而访问自己的实例变量是隐含的self->;同样,没有self 指针,这是不可能的。
    【解决方案2】:

    * 是 C、C++ 和 Objective-C 的解引用运算符。理解解引用操作符和一般的内存管理比 Objective-C 广泛得多。这是任何 C/C++/Objective-C 开发人员的基本技能。查看网上的大量介绍 C 教程以了解更多信息。

    编辑:任何关于 c 指针的教程都可以。比如这个http://home.netcom.com/~tjensen/ptr/pointers.htm

    【讨论】:

    • 声明中的 * 不是运算符;它是声明的一部分。
    • x = *y 表示获取存储在 y 持有的地址的值。我们在这里没有宣布任何事情。它是一个解引用运算符。
    • 问题中引号中的星号在声明中 (NSArray *array;)。
    【解决方案3】:

    在 Cocoa 中,您永远不会使用堆栈分配的对象;所有对象都将以 * 开头(请记住,类型“id”实际上是“指向某些对象的指针”的另一个词)并在堆上创建。

    你将永远拥有这个:

    NSArray     *myArray;
    

    永远不要这样:

    NSArray     myArray;
    

    你可以忽略第二个块,因为你总是取消引用指针。

    【讨论】:

    • 这根本不是真的。 NSRectNSPoint 等属于 Cocoa,可以在栈上分配。编辑:当您使用“对象”一词时,我想我误解了,“对象”是指Objective-C对象,对吗?
    • 梦想:公平地说,那些不是对象。 ben 声明你永远不会使用堆栈分配的对象。
    • 我想我的主要问题是堆栈和堆之间的区别......有什么好的资源吗?
    • 嗯,有一个在线视频讲座youtube.com/…从第1讲到第14讲讲C语言,堆栈,堆,函数调用等。我很久以前看了所以不能指导你到确切的部分。
    【解决方案4】:

    希望这些幼稚的玩具例子可以帮助到你。

    在 C 语言中,在函数中,

    int x; // x is a variable of type int in stack
    int *xp; // xp is a variable of type int * (pointer to int) in stack
    int *xp2 = (int *) malloc(sizeof(int)); // xp2 is a variable in stack, it points to a memory location(size is of int) in heap
    xp = &x; // xp can point to x
    xp = xp2; // xp can also point to what xp2 points to
    free(xp2); // now xp and xp2 point to a freed memory, BAD to use xp and xp2 now.
    int **y; // y is a variable in stack, type is int **
    y = (int **) malloc(sizeof(int *)); // allocate a piece of memory in heap, to hold a pointer to int(int *)
    *y = (int *) malloc(sizeof(int)); // allocate a piece of memory in heap, to hold an int
    **y = 100; // now we can use it
    free(*y);
    free(y);
    

    在 C++ 中,在函数或成员函数(方法)中,

    SomeClass a1; // a1 is an object of type SomeClass in stack
    SomeClass *a2 = new SomeClass(); // a2 is a pointer(in stack) pointing to an object(of type SomeClass) located in heap
    delete a2;
    

    所以在 C++ 中,对象可以存在于栈或堆中

    在 Java 中,在函数或方法中,

    SomeClass b1; // b1 is just a reference, no object exists yet
    b1 = new SomeClass(); // in java, objects can only exist in heap
    int x; // however, primitive types are in stack, 
    

    在 Objective-C 中,在函数或方法中,

    SomeClass c1; // you can't do this.
    SomeClass *c2 = [[SomeClass alloca] init]; // c1 is a pointer in stack, pointing to an object in heap
    [c2 release];
    

    【讨论】:

      猜你喜欢
      • 2011-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-03
      • 1970-01-01
      • 2017-11-06
      相关资源
      最近更新 更多