2

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

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

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

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

呵呵

4

4 回答 4

9

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

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

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

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

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

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

有关更多信息,请参阅我的指针教程

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

呵呵

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

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

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

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

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

于 2010-01-13T06:09:35.350 回答
4

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

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

于 2010-01-13T05:20:32.440 回答
2

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

你将永远拥有这个:

NSArray     *myArray;

从来没有这样:

NSArray     myArray;

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

于 2010-01-13T05:24:59.577 回答
2

希望这些幼稚的玩具示例可以帮助您。

在 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];
于 2010-01-13T06:21:21.310 回答