为什么我应该在这种情况下使用自动释放?

时间:2013-01-04 10:30:41

标签: ios memory-management autorelease reference-counting

我是一个客观的新手,我只是不明白为什么发布不属于我的对象是个坏主意。

假设我在名为Europe

的方法中有这个
//initForStringTheory is a class init method;
Collider *LHC = [Collider initForStringTheory]; 

//Colliders is a NSMutableArray
[Colliders addObject: LHC]  

[LHC release]

我建议不要在LHC中发布Europe,因为Europe不拥有LHC,它只有一个指向它的指针。因此,我应该充分利用自动释放池并执行

//newCollider is a pointer for the newly created instance in initForStringTheory
return [newCollider autorelease]; 
initForStringTheory中的

。但为什么呢?

Europe中的指针也不指向实例吗?为什么我不能在LHC中发布Europe而不是在init方法中返回自动释放newCollider

2 个答案:

答案 0 :(得分:1)

Stavash基本上说明了你是否释放它取决于该方法是否返回了一个保留实例。

但是,您并不需要知道方法的作用才能正确使用内存管理。 Cocoa MRC内存管理遵循基于方法名称的方法做什么的规则。根据规则,名称以allocretainnewcopymutableCopy开头的方法会返回保留的实例,并且调用方负责释放它。所有其他名称的方法返回一个非保留的实例,调用者不应该释放它。

因此,假设(当然,这是一个很大的假设)initForStringTheory正确遵循规则,它不应该返回保留实例(这并不意味着它必然是autorelease d ;它可能被其他东西保留,只是直接返回给你)。

问题的另一部分是,将类方法命名为init...是非常不寻常的。通常,以init开头的实例方法是构造函数,它们立即在创建实例的alloc的结果上运行。那么名为init...的类方法到底有什么用呢?此外,按照惯例,init方法有一个特殊的规则,它消费"消费"由alloc返回的保留实例,并返回一个(不一定相同)保留的实例。但是如何适用于这种情况,在类上调用它?会不会消费"对类对象的保留计数(什么都不做),然后返回一个保留的实例?没人知道。

总而言之,这段代码确实需要重新编写。绝对没有名为init...的类方法。并确保您编写的所有方法都具有基于其名称正确遵循规则的内存管理行为。

答案 1 :(得分:0)

这是initForStringTheory返回的问题 - 如果这是一种方便的初始化方法,例如[NSArray arrayWithObjects...][NSString stringWithFormat...],它会创建一个自动释放的实例,将它添加到您的收藏后,您无需发布。但是,如果这是一个返回初始化的非自动释放实例的初始化,则您有责任在将其添加到集合后立即在方法中释放本地实例定义。

添加对象时,保留计数加1,因此您不希望它为2,因为您在实例化后没有释放/自动释放它(会导致内存泄漏< / strong>因为对象永远不会被释放,即使它不在数组中。)

阅读本文: http://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html