在objective-c中正确创建对象以避免内存泄漏

时间:2010-09-03 09:30:33

标签: objective-c memory-leaks

在尝试掌握语法和规则花了几个月之后,我对内存管理规则进行了深入研究。 我不明白并且让我感到困惑的一件事是如何创造物体。

根据Apple内存管理指南中的说明,以下是一种有效的方法:

– (NSArray *)sprockets {
    NSArray *array = [NSArray arrayWithObjects:mainSprocket,auxiliarySprocket, nil];
    return array;
}

因为我没有造成任何内存泄漏。 原因是它没有使用alloc来创建数组,因此sprockets不是所有者。 但是我现在想知道arrayWithObjects里面有什么。 因为在我的应用程序中,我经常使用类似于以下内容创建自定义对象的工厂:

return [[MyObject alloc] initWithParameter:(id)params]; // possible leak

如果我想用静态方法改变,如:

return [MyObject initWithParameter:(id)params];

在initWithParameter中可以遵守内存规则吗?如果MyObject扩展了其他一些对象怎么办?我还发现方法命名规则对于正确建议程序员很重要,这个规则是什么? 你也可以指出一个解释这个问题的网络链接(我还不擅长在苹果网站上找到文档)。

感谢

2 个答案:

答案 0 :(得分:1)

这是您要查找的页面:Memory Management Rules。这一切都归结为坚持对象的所有权规则。

如果使用alloc创建对象,则您拥有该对象并且必须将其释放。例如:

NSString* str = [[NSString alloc] init]; 
//do something with your str object 
[str release];
str = nil; //don't forget to set it to nil, it's still 
           //pointing to the (now unallocated) block of memory

如果使用工厂方法创建对象,例如:

NSString* str = [NSString stringWithString:@"blah"];

然后这里发生的是它正在使用alloc为您创建字符串对象,然后返回该对象,但首先将其添加到本地自动释放池。要在您的问题中使用该示例。

return [[MyObject alloc] initWithParameter:(id)params]; // possible leak
return [[[MyObject alloc] initWithParameter:(id)params] autorelease]; //now autoreleased -- no leak

以下是Autorelease Pools上的页面。 Apple说它比我好。

  

自动释放池是NSAutoreleasePool的一个实例,它“包含”已收到自动释放消息的其他对象;当自动释放池被释放时,它会向每个对象发送一条释放消息。可以将对象多次放入自动释放池中,并在每次将对象放入池中时收到释放消息。因此,发送自动释放而不是释放到对象会延长该对象的生命周期,至少直到池本身被释放(如果在临时中保留该对象,则该对象可以存活更长时间)。

方法命名规则很重要,因为它可以很好地指示方法是否返回自动释放的对象。在这个例子中,我将命名方法:

[MyObject myObjectWithParameter:(id)param]

希望这有所帮助。

答案 1 :(得分:-1)

分配和创建方法返回保留对象的标准做法。任何以init,create或对象名称开头的东西都会让其他程序员了解该方法的目的。

即使您使用alloc创建,如果您的方法的目的是传递所有权,您也不应该释放该对象。