11

可能的重复:
学习 Obj-C 内存管理
iPhone 内存管理的最佳解释在哪里?

我来自 C/C++ 背景,Objective-C 的动态特性对我来说有些陌生,是否有任何人可以向我指出 Objective-C 中一些基本内存管理技术的好资源?前任。保留、释放、自动释放

例如,使用指向 Objective-C 对象的指针并将其视为数组是完全非法的吗?您是否被迫将 NSArray 和 NSMutableArray 用于数据结构?

我知道这些都是相当新手的问题,感谢您为我提供的任何帮助。

4

10 回答 10

19

给你

应用程序内存管理是在程序运行时分配内存、使用它并在完成后释放它的过程。一个编写良好的程序使用尽可能少的内存。在 Objective-C 中,它也可以看作是在许多数据和代码之间分配有限内存资源所有权的一种方式。完成本指南的工作后,您将掌握管理应用程序内存所需的知识,方法是显式管理对象的生命周期并在不再需要它们时释放它们。

尽管内存管理通常是在单个对象级别考虑的,但您的目标实际上是管理对象图。您想确保内存中没有比实际需要更多的对象...

于 2008-09-20T00:52:45.063 回答
13

重复内存管理的基本规则通常是没有用的,因为你几乎总是会犯错误或不完整地描述它们——就像'heckj'和'benzado'提供的答案一样......

内存管理规则的 Apple 文档中提供了内存管理的基本规则

来自“www.stray-bits.com”的答案:声明从“非拥有”方法返回的对象是“自动释放”的,充其量也是一种误导。您通常不应该考虑某些东西是否“自动释放”,而只需考虑内存管理规则并根据这些约定确定您是否拥有返回的对象。如果你这样做,你需要放弃所有权......

一个反例(考虑自动释放对象)是当您考虑与方法相关的性能问题时,例如stringWithFormat:. 由于您通常 (1) 无法直接控制这些对象的生命周期,因此它们可能会持续较长时间并不必要地增加应用程序的内存占用。虽然在桌面上这可能没什么影响,但在更受限制的平台上,这可能是一个重大问题。因此,在所有平台上使用alloc/init模式被认为是最佳实践,在更受限制的平台上,强烈建议您尽可能不要使用任何会导致自动释放对象的方法。

(1) 您可以使用自己的本地自动释放池进行控制。有关这方面的更多信息,请参阅Apple 的内存管理编程指南

于 2008-09-28T20:54:03.803 回答
2

Objective-C 只是 C 的超集。你可以在 C 中做的任何事情在 Objective-C 中都是有效的。

于 2008-09-20T03:53:10.917 回答
2

以下是规则:

  1. 如果您通过调用allocor创建一个对象copy,则您拥有它并且release在完成后必须拥有它。
  2. 如果你没有创建一个对象,但希望它确保它在控制返回到运行循环之前一直存在(或者,为了简单起见,你的方法返回),给它发送一条retain消息,然后release在你完成后发送它.
  3. 如果您创建一个对象并希望从您的方法中返回它,您有义务释放它,但您不想在调用者有机会看到它之前销毁它。所以你发送它autorelease,它把它放在自动释放池中,一旦控制回到程序的事件循环,它就会被清空。如果没有其他人保留该对象,它将被释放。

关于数组,你可以自由地做这样的事情:

NSObject *threeObjects[3];

threeObjects[0] = @"a string";
threeObjects[1] = [NSNumber numberWithInt:2];
threeObjects[2] = someOtherObject;

无论如何使用 NSArray 的原因:

  • NSArray 会在您添加对象时保留它们,并在您删除它们时释放它们,而在纯 C 数组中您必须自己做。
  • 如果您将数组作为参数传递,则 NSArray 可以报告它包含的对象的数量,使用普通的 C 数组您也需要传递一个计数。
  • 在一行上混合方括号的含义感觉很奇怪:

    [threeObjects[0] length]

于 2008-09-24T09:11:10.353 回答
2

您当然可以使用数组并进行自己的内存管理。最大的组成部分是,如果您正在创建任何 NSObject 子类,并且您使用 [XXX alloc] 方法创建它,或者如果您使用 [xxx copy] 从另一个副本中获取它,那么您有责任将其与相关版本匹配。

如果从任何地方获取一个变量并打算保留它超过您正在执行的直接使用,那么请确保您在其上调用 [... retain]。

链接http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html包含所有详细信息,绝对是第一个阅读的地方。

于 2008-09-20T04:01:20.803 回答
2

如果它是一个数组,请随意使用指针进行迭代。常规数组仍然由 C 管理。如果它是 NSArray,请阅读 NSArray 文档。如果他们说要以特定的方式做,那就那样做。为 OS X 编写代码时,请按本书进行。

于 2008-09-20T01:20:06.137 回答
1

如果您使用 C 风格的数组来存储对象并决定使用垃圾回收,需要注意的是,您需要分配该内存NSAllocateCollectable(sizeof(id)*size, NSScannedOption)并将该变量标记为__strong.

这样,收集器就知道它持有对象,并将在该变量生命周期内将存储在那里的对象视为根。

于 2008-10-01T18:42:22.360 回答
1

例如,使用指向 Objective C 对象的指针并将其视为数组是完全非法的吗?

如果它不是一个数组,那么是的。

您是否被迫将 NSArray 和 NSMutableArray 用于数据结构?

不。您可以使用 C 数组,并且应该能够使用 C++ STL 向量(虽然我不使用 C++,所以我不知道具体如何)。

但是没有理由不使用NS{,Mutable}Array. 不要害怕 Cocoa 框架,因为它们是你的朋友。

并且不要忘记其他集合类型,例如NS{,Mutable}SetNS{,Mutable}Dictionary

于 2008-11-10T16:39:39.440 回答
1

作为另一位新手,我发现斯坦福 iOS 讲座非常有用:http: //itunes.apple.com/itunes-u/developing-apps-for-ios-hd/id395605774

这很好,因为它通过演示展示了实际的概念,而且我通常发现与我交谈的人比仅仅阅读更能吸收。

我绝对认为这是您必须通过不同来源学习和重新学习的主题之一……只是将其锤入您的脑海。

于 2011-01-04T16:17:42.753 回答
0

可能还需要注意的是,对于像 NSString + (NSString *)stringWithFormat: 这样的类消息(基本上,为您分配对象而不是要求您自己分配对象的帮助消息),生成的对象会自动释放,除非您明确保留它。

于 2008-09-22T14:02:49.827 回答