如何为创建但未分配给任何指针的对象管理内存?

时间:2013-06-28 20:28:40

标签: objective-c memory-management memory-leaks automatic-ref-counting reference-counting

这可能是一个愚蠢的问题,但它一直困扰着我。

假设我们有一个方法将NSString对象作为其参数并对NSString对象执行某些操作,

- (void)someMethod:(NSString *)str
{
    //do something with str
}

考虑这段代码

[someObject someMethod:[[NSString alloc] initWithFormat:@"Hello World!"]];

由于alloc已用于创建字符串作为someMethod的参数,因此无论是在ARC前环境中还是在ARC下隐式显示,都必须由release进行平衡。但似乎我们无法获得指向字符串的指针,因为我们从未将其指定给任何指针。

所以我的问题是,首先,这是在编写客观c代码时禁止传递参数的方法吗?如果不是,那么这种方式创建的对象如何被释放?最后,这段代码会导致内存泄漏吗?


仅供记录,我理解上面的代码是写的

NSString *string = [[NSString alloc] initWithFormat:@"Hello World!"];
[someObject someMethod:string];
// [string release]; depending on ARC or non-ARC

3 个答案:

答案 0 :(得分:2)

实际上,该对象分配给名为str的变量,该变量是您方法的参数。您可以通过该指针管理方法内的内存,尽管方法不应该取其参数的所有权(除了下面的内容)。

ARC知道在这种情况下该怎么做 - 它将自动释放对象或在方法完成后添加一个版本。

在MRR下,您的代码片段会泄漏;正确的方法是发送autorelease

[someObject someMethod:[[[NSString alloc] initWithFormat:@"Hello World!"] autorelease]];

或使用你的最后一个片段(将字符串放入临时变量并稍后释放)。

作为一个稍微深奥的选项,您的方法可以使用ns_consumed属性声明它拥有该参数:

- (void)someMethod:(NSString *) __attribute__((ns_consumed)) str;

这表明您的方法应该在返回之前将release发送给对象 - ARC也会处理它。

答案 1 :(得分:1)

  

所以我的问题是,首先,这是在编写目标c代码时禁止传递参数的方法吗?

没有。这完全合法。

  

如果不是,那么这种方式创建的对象如何被释放?

ARC将为您解决这个问题。如果你自己进行引用计数,那么你可以在它超出范围之前将它添加到自动释放池中:

[someObject someMethod:
  [[[NSString alloc] initWithFormat:@"Hello World!"] autorelease]];
                                                     ^^^^^^^^^^^
  

最后,这段代码会导致内存泄漏吗?

不在ARC。在MRC中,您需要添加-autorelease

静态分析仪也会指出泄漏。

答案 2 :(得分:0)

没有理由不写代码,因为你要求考虑......没有丝毫禁止的东西。这些对象的释放方式与释放任何其他对象的方式相同。缺少将指针存储在顶层的变量并不重要,因为Objective C运行时知道对象。