4

这是我正在编写的一些代码的要点。我担心我没有正确解决 NSMutableArray 上的数组类方法的保留/释放问题。以下实际上是泄漏内存吗?

for(a while) { 
    // do stuff
    NSMutableArray *a = nil;
    // do stuff
    if (!a) {
        a = [NSMutableArray array];
    }
} // for(a while)
4

4 回答 4

12

您不会在此代码中泄漏内存,并且当数组在运行循环结束时自动释放时,您自己释放数组会导致崩溃。

大多数 Cocoa 类提供了几种创建新对象的方法,并且非常符合这个约定:

  1. [[NSSomeObject alloc] init]:你负责释放对象(实例方法)。

  2. [NSSomeObject someObject]: 对象会为你自动释放,通常在运行循环结束时(类方法)。大致相当于[[[NSSomeObject alloc] init] autorelease].

实例方法的正确使用是:

a = [[NSMutableArray alloc] init];
// do stuff
[a release];

类方法的正确使用是:

a = [NSMutableArray array];
// do stuff, array is in the autorelease pool

请注意,Apple 建议您尽可能远离便利方法以提高性能。这是一个有争议的建议,可能不会节省太多处理器时间,并且将 alloc-init 与释放的对象分开,您实际上可能不太关心保留。

于 2009-06-13T16:25:00.373 回答
6

来自Cocoa 内存管理规则

如果您使用名称以“alloc”或“new”开头或包含“copy”(例如,alloc、newObject 或 mutableCopy)的方法创建对象,或者向其发送保留消息,则您将获得对象的所有权。您有责任放弃使用 release 或 autorelease 拥有的对象的所有权。任何其他时间您收到一个对象,您都不能释放它。

因此用这条线:

a = [NSMutableArray array];

您不拥有该阵列的所有权,它将被自动释放传递给您。内存会由自动释放池自动为你处理,一旦不再使用,就会为你释放。但是,如果您想将数组保留在当前事件之外,则必须保留它,否则它将为您释放。

于 2009-06-13T16:01:34.627 回答
2

是的,如果你想让它坚持下去。

返回的对象是一个自动释放的对象,当它的自动释放池被清除时将被释放。

所有以“array”开头的数组类方法都返回这些类型的自动释放对象。

阅读 Apple 的此文档

于 2009-06-13T16:02:25.747 回答
0

这是有效的。当您有问题时,手动管理事情可能会有所帮助,以便学习。

有一个约定:

  • init 前缀 (init, initWithString:) 表示保留计数为 1,其中
  • objectname prefixes (string, stringWithString:) 表示一个自动释放的对象

多年来,我有一个习惯,就是在呼叫站点发布我可以发布的内容,而不是推动它自动发布。然后,一些自动释放问题变得非常难以追踪。当然,在这种情况下,自动释放对程序员来说是一种便利(前提是没有出错),但会对重用、清晰度和性能产生不利影响(在大型代码库/程序中更是如此)。

于 2009-11-18T08:04:56.690 回答