【问题标题】:Help me understand memory management in Objective-C and Cocoa帮助我理解 Objective-C 和 Cocoa 中的内存管理
【发布时间】:2009-10-15 18:27:52
【问题描述】:

别开枪,我知道这肯定被问了一千遍了……

我对缺少关于 Objective-C 内存的良好文档感到不舒服。我理解 alloc、dealloc、retain、release 以及所有这些,但我的脑海中留下了一些混乱。

这只是懒惰的编程还是 Objective-C 在分配内存方面做了一些“幕后”的自动活动?

来自 C 背景(几个世纪前),我知道指针只是指针......您还必须为指针指向的内容保留空间,否则您将开始踩踏您自己的程序和其他变量。

我找到的代码示例(并且在我阅读的书中 - 所有这些都与当前版本的 XCode 和 Interface Builder 过时)似乎从未为某些对象分配存储空间,例如 NSString。他们声明一个指针(例如 NSString *aString;)然后开始为字符串分配文本。每次调用都没有为字符串分配内存!?!?那么所有这些示例都只是寻找崩溃位置的懒惰代码吗?

此外,书籍还谈到了声明“池”内存以及它会自动插入到您的代码中。当我创建项目、类和对象时,在任何地方都找不到这样的代码。 Apple 是否取消了这种自动插入,还是在编译期间发生了这种情况?

是否有倒数第二本可以一劳永逸地解释这一切的参考书或网站?

【问题讨论】:

  • 如果您查看 main.m,您会注意到 main 函数中的所有内容都已放入自动释放池中......并且池不是“内存池”。取而代之的是,将其视为一个列表,该列表跟踪一组标记为以后释放的对象。当池被耗尽时,通过 [pool drain],检查池中每个对象的保留值,如果没有保留它们并设置为自动释放,则该对象被销毁。

标签: objective-c memory-management


【解决方案1】:

【讨论】:

  • 如果可以的话,我会 +10。这是 Cocoa 内存管理的终极资源。
【解决方案2】:

我认为可用于理解 Objective-C 语言中的内存管理的最佳参考资料是 Objective-C 2.0 编程语言,Apple 在以下网址:

http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/ObjC.pdf

第 3 章 分配和初始化对象 谈到内存管理。

一个不太详细但更简洁关于Objective-C语言内存管理的讨论可以在Very simple rules for memory management in Cocoa找到:

http://www.stepwise.com/Articles/Technical/2001-03-11.01.html

您关于 NSString 分配规则的具体问题已在标题保留计数规则下的文章中介绍。

“使用便利构造函数(例如 NSString 的 stringWithString)创建的对象被认为是自动释放的。”

另一本了解 Cocoa 编程的好书,其中包含许多示例和解释,是 Cocoa Programming for Mac OS X(第 3 版),可在此处从 Amazon 获得:

http://www.amazon.com/exec/obidos/ASIN/0321503619/bignerdranch-20

作者 Aaron Hillegas 从 Next days 开始就一直在使用 Objective-C 编程,现在以教授 Cocoa 编程为生。我拥有这本书,但我没有它,所以我不能告诉你现在要看的具体章节。不过,我可以向你保证,这是一本好书。

希望以上参考资料对您的理解有所帮助。

【讨论】:

【解决方案3】:

你可能遗漏了两点:

  1. 诸如[NSString stringWIthString:theString] 之类的工厂方法在内部执行相当于[[[NSString alloc] initWithString:theString] autorelease](或者可能是字面意思)。 autorelease 与您提到的 NSAutoReleasePool 交互,基本上是尝试在下一个事件循环周期中释放对象。
  2. 所有 Objective-C 对象都是指针。不是直接使用mallocnew,而是从NSObject(Apple 的Objective-C 库和大多数Objective-C 代码中的根类)继承的Objective-C 对象使用+(id)alloc 代替直接内存管理调用。同样,在内部这可能使用malloc 进行分配。

【讨论】:

    【解决方案4】:

    Objective-C 2.0 有一个垃圾收集器。

    是 NSString *aString;会为你做一些幕后的魔术。如果你想控制内存,你可以使用类似的东西:

    NSString* aString = [[NSString alloc] init];

    您是否阅读过“在 Mac 上学习 Objective C”?这有点过时了,但不是我的太多。主要区别在于 XCode。

    【讨论】:

    • 我建议学习内存管理,不要依赖垃圾回收。 iPhone 环境不支持垃圾回收。
    • 什么?声明一个 NSString 指针变量并没有在幕后做任何神奇的事情。
    • 谢谢大家。我找到了两个我将研究的参考资料: Core Foundation 的内存管理编程指南(在其中一个回复中提到)developer.apple.com/mac/library/documentation/Cocoa/Conceptual/… Cocoa 的内存管理编程指南developer.apple.com/mac/library/documentation/Cocoa/Conceptual/… 是的,我有“Mac OS X 的 Cocoa 编程”但这是第二版。它帮助我开始了,但由于示例代码中的一些重大遗漏,我或多或少地放弃了它。
    【解决方案5】:

    当然,这个问题很久以前就被问过了,这里已经给出了很好的答案。 但目前至少有一个已经过时了——关于垃圾收集器的那个

    如果有人来这里找书,这里有一本: https://www.packtpub.com/application-development/objective-c-memory-management-essentials

    我是那里的合著者,是的,这就是我无法通过的原因.. :) 欢迎任何批评者!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-25
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      相关资源
      最近更新 更多