【问题标题】:Objective C: Memory Allocation on stack vs. heap目标 C:堆栈与堆上的内存分配
【发布时间】:2010-12-01 17:10:07
【问题描述】:

我对什么时候在堆上分配(我需要释放它们)以及什么时候在堆栈上分配(我不需要释放它们)感到有些困惑。

有经验法则吗?

我认为在 C++ 中,经验法则是,如果您使用 new 关键字,它们就在堆上。目标 c 的规则是什么?我怎么知道什么时候在堆栈上分配了东西?

这行代码会被分配到栈上吗?

NSString *user = @"DEFAULT";

【问题讨论】:

    标签: objective-c memory-management


    【解决方案1】:

    Objective-C 在这方面很容易。

    所有 Objective-C 对象总是在堆上分配。

    或者,至少应该将它们视为在堆上。

    为:

    NSString *user = @"DEFAULT";
    

    字符串对象在技术上不在堆中,但也可能在堆中。也就是说,它是由编译器生成的,并且是应用程序二进制文件的一部分。它不需要保留和释放,因为类 (NSCFConstantString, IIRC) 覆盖了保留/释放/自动释放,实际上什么都不做。

    至于何时释放和不释放对象,您应该阅读(并重新阅读)Objective-C memory management guide

    (还有一个例外,但它是一个相当深奥的细节;块从堆栈开始,您可以 Block_copy() 将它们放到堆中。块也恰好是 Objective-C 对象,但这很少在使用。)

    【讨论】:

    • 由于块异常而赞成,当您希望在声明块的范围内销毁后使用块时,您应该制作一份副本。复制将一个块移动到堆中。
    【解决方案2】:

    在 Objective-C 中,这很简单:所有对象都在堆上分配。

    规则是,如果您调用名称中带有allocnewcopy 的方法(或者您调用retain),则您拥有该对象,并且您必须稍后释放它当你完成它时。有很多关于这个主题的文章。

    你给出的例子是一个特例:那是一个静态字符串,我相信它实际上位于程序的数据段(在堆上),但它是静态的,所以你不必担心释放它。

    【讨论】:

    • 我认为retain也应该在列表中。
    • Keep in mind 表示块默认分配在堆栈上。
    【解决方案3】:

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

    NSString *user = @"DEFAULT";
    

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

    【讨论】:

    • 确实没有所谓的“恒定记忆”,尽管它是一个准确的描述。它实际上是来自磁盘上的 mach-o 文件(或 dyld 共享缓存)的 mmap 只读内存。
    • 我的意思是静态内存,嵌入在二进制文件中。错了:)
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2011-05-28
      • 1970-01-01
      • 2023-03-03
      • 2017-01-04
      • 2018-07-24
      • 1970-01-01
      • 2011-10-06
      • 2011-10-09
      相关资源
      最近更新 更多