Objective C:栈内存分配和堆内存分配

25

我有些困惑,不知道什么时候需要在堆上分配内存(需要释放),什么时候在栈上分配内存(不需要释放)。是否有经验法则?

我认为在C++中,经验法则是如果你使用new关键字,则它们在堆上。在Objective-C中的规则是什么?我如何知道某个东西是在堆上分配的?

这行代码会在栈上分配吗?

NSString *user = @"DEFAULT";
4个回答

38

在这方面,Objective-C非常容易。

所有的Objective-C对象都始终分配在堆上。

或者至少应该被视为在堆上。

因为:

NSString *user = @"DEFAULT";

字符串对象并非严格在堆中,但实际上可以看作在堆中。也就是说,它由编译器生成,并成为应用程序二进制文件的一部分。它不需要保留和释放,因为该类(NSCFConstantString,如果我没记错)重写了retain/release/autorelease方法,以实际上什么都不做。

至于何时需要释放对象和不需要释放对象,你应该阅读(反复阅读)Objective-C内存管理指南

(还有一个例外,但这是一个相当晦涩的细节;块始于堆栈,您可以将它们Block_copy()到堆中。块也恰好是Objective-C对象,但在使用中很少暴露出来。)


4
因为blocks异常,您应该在预计语句块在声明其所在的作用域销毁后继续使用时复制它。复制会将block移动到堆上。 - Pablo A.

37

在 Objective-C 中,一切对象都容易地分配在堆上。

规则是,如果您调用具有allocnewcopy名称的方法(或者您调用了retain),则您拥有该对象,并且您必须在以后某个时候释放它,当您用完它时。这方面已经有很多文章写过。

您给出的示例是一个特殊情况:那是一个静态字符串,我相信它实际上位于程序的数据段(堆)中,但它是静态的,所以您不需要担心释放它。


2
我认为“retain”也应该在列表中。 - sixtyfootersdude
请记住,块默认情况下是在堆栈上分配的。 - DanSkeel

1

Objective-C 中没有对象的堆栈分配(块是另一种情况,我不会在这里讨论)

NSString *user = @"DEFAULT";

这会在常量内存中分配一个NSConstantString对象,而不是在堆栈上。


2
实际上,"常量内存"并不存在,尽管这是一个准确的描述。它实际上是从磁盘上的mach-o文件(或dyld共享缓存)映射的只读内存。 - bbum
我指的是静态内存,嵌入到二进制文件中。说错了 :) - Joshua Weinberg

1
在Objective-C(以及许多其他语言)中,对象只是具有特定布局的连续内存块。对象通常在堆上创建。对象指针变量本身的存储在堆栈上,但它所指向的对象在堆上。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接