Objective-C:自动释放的对象作为方法的参数

时间:2011-09-22 16:15:39

标签: objective-c memory-management

以下代码会导致问题吗?

- (void) method1 {
      NSMutableArray *myArray = [[[NSMutableArray alloc] init] autorelease];

      ... fill the array

      [someObject someMethod:myArray]; // someObject does work on that array (without retain!)
}

我的应用程序中有时出现的崩溃看起来像是一个问题;但我不明白......至少在方法1结束之前,myArray不应该活着吗?

非常感谢你的帮助!

所以我的问题除了“这可能是个问题”之外: - 是否足以删除自动释放并在方法结束时发布? - 如果没有:我是否必须在“someMethod”中保留/释放?

编辑:但这可能是一个问题,我是对的吗?

- (void) method1 {
      NSMutableArray *myArray = [self getArray];

      ... fill the array

      [someObject someMethod:myArray]; // someObject does work on that array (without retain!)
}

- (NSMutableArray) method2 {
      return [[[NSMutableArray alloc] init] autorelease];
}

4 个答案:

答案 0 :(得分:0)

我将暂时假设您认为这是NSMutableArray而不是NSArray。如果你的意思是NSArray,那么这一切都是不可能的。你不能在不可变数组上“填充数组”。

是的,这应该有效。您的问题可能在其他地方。这里常见的错误是过度释放你放入myArray的内容。

答案 1 :(得分:0)

看起来您在分配数组的行上缺少几个左括号。应为[[[NSMutableArray alloc] init] autorelease];

答案 2 :(得分:0)

您的代码完全正确。不要听人们告诉你删除自动释放并在调用someMethod:后手动释放阵列。

在使用autorelease'd对象的99%的情况下,绝对对您的应用程序没有负面的性能影响。你想要担心的唯一一次是循环。

[[[Foo alloc] init] autorelease]模式与使用[NSString stringWithFormat:...]等内置辅助方法相同。它们都返回一个自动释放的对象,但你可能不担心后者的性能。同样,只关心大循环中的自动释放,或者当仪器告诉你有问题时。

使用[[[Foo alloc] init] autorelease]样式也可以将所有内存管理保留在一行中。如果您习惯于键入[[[,则不会忘记发布。如果您要复制并粘贴代码或移动代码,则不会意外丢失相应的release,因为它们都在同一行。

查看使用[[[Foo alloc] init] autorelease]样式的代码也更容易,因为您不必在方法的后面寻找release以确保内存管理正确。

因此,在可读性,安全性和正确性方面,您的代码绝对优秀且良好。这适用于您的原始代码段和您在下面添加的后续内容。当你有大循环时,自动释放的性能只会成为一个问题。

您的崩溃问题必须由您发布的代码中不明显的其他因素引起。

如果您还没有,我建议您阅读Memory Management Programming Guideline。基本上,自动释放的对象保证在释放封闭池之前保持有效。在您的情况下,自动释放池存在于调用堆栈中的较高位置(可能是主runloop),因此您可以安全地知道自动释放的阵列在您进行的任何调用期间都将保持有效。

最后一点。您的数组分配代码也可以使用array辅助构造函数:

NSMutableArray *myArray = [NSMutableArray array];

这比原来更简单,更简洁,更短。

答案 3 :(得分:-2)

最好的事情就是这样:

- (void) method1 {
      NSMutableArray *myArray = [[NSMutableArray alloc] init];

      ... fill the array

      [someObject someMethod:myArray]; // someObject does work on that array (without retain!)
      [myArray release];
}

从两个不同的角度来看最好。你拿着你的阵列直到你不需要它的一种方式,所以在你说之前它不会从内存中擦除。第二个是同一个句子,唯一的原因是你可以在没有更多需要的对象的情况下尽快清理内存。
最后可能需要更多的解释...自动释放的对象应该尽快自动释放因为你不需要它,但是它们在两个基本规则上被释放:在块结束时(并非总是)或在块结束后的内存压力(是的总是)。换句话说,NSAutoreleasePool并不总是在某些代码块的末尾发布内容,并且它甚至不会很少将它们延迟到稍后的版本。
无论如何,你应该总是检查是否过度释放您的对象,因为当您尝试在代码中访问此类对象时,它会导致崩溃。