2012-01-21 102 views
1

我已经读过,将调用一个对象的dealloc,只有当该对象的保留计数变为零时才会被调用。iOS内存泄漏

我在接口部分以一个对象UIColor和设置属性

UIColor *currentColor; 
@property (nonatomic, retain) UIColor *currentColor; 

在implemetation部分使用这个对象后,我呼吁释放的方法该对象在dealloc

-(void)dealloc 
{ 
    [currentColor release]; 
    [super dealloc]; 
} 

我怀疑dealloc将如何被调用这个对象,因为我没有在任何地方释放保留的对象。提前致谢。

回答

2

将被调用,只要保留该对象的 计数变为零,最好的地方我读过的dealloc的对象。

是的。

为了简单起见,请将包含currentColor对象的类称为ColorContainer。现在,如果你创建的ColorContainer像下面的一个实例:

ColorContainer* containerColor = [[ColorContainer alloc] init]; // retain count + 1 

containerColor保留计数变为1。

假设您创建了一个UIColor的实例,并将该实例设置为currentColor属性。在这种情况下,您可以采用两种不同的方式。 在第一个中,您可以创建如下的实例。如果您使用像initWithRed:green:blue:alpha:这样的实例方法,则必须明确释放内存。

UIColor color* = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:1]; // retain count + 1 
containerColor.currentColor = color; // retain count +1, the referenced object has a retain count of 2 because you use a retain policy 
[color release]; // retain count -1, now the referenced object has a retain count of 1 

在第二种方法中,您可以使用类方法(+符号)。在这种情况下,您不需要释放内存显式,因为在该类方法中创建的对象将在应用程序生命周期的某个时间点自动释放。

containerColor.currentColor = [UIColor whiteColor]; // retain count +1 

现在假设您发布了containerColor对象。如果containerColor的保留计数等于1,则将其从使用该对象的对象中释放,它允许调用其dealloc方法,因此也可以消除由currentColor引用的对象。

在你要注意到,currentColor引用的对象是完全从内存(解雇)移除了这个简单的案例,只有当它有保留的。事实上计数,如果你这样做

UIColor color* = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:1]; // retain count + 1 
containerColor.currentColor = color; // retain count +1, the referenced object has a retain count of 2 
//[color release]; 

你创建了一个内存泄漏(你明白了吗?)。

总之,当你使用retaincopyinitnew(这是相同的alloc-init),你必须总是叫对口releaseautorelease

作为一个经验法则,您需要总是平衡对象的保留计数以避免内存泄漏。

所以,作为一个美眉,你可以像树一样思考记忆。假设你有一个父母(containerColor)和一个孩子(currentColor)。如果父(保留计数为1)被释放,它会导致为其对象调用其dealloc方法和空闲内存。如果在其dealloc方法中释放一个子项(保留计数为1),它会导致调用其dealloc方法和空闲内存。如果孩子的保留数大于1,则会导致内存泄漏。

希望它有帮助。

编辑

对于你能读懂About Memory Management进一步的信息。自iOS 5 Apple推出ARC以来,自动引用计数是一种编译器机制,提供Objective-C对象的自动内存管理。有关信息,请参阅Transitioning to ARC Release Notes

+0

Hello Flex,非常感谢您的回答。 – karthick

+0

不客气! –

0

如果您分配对象(通过alloccopyretain),则应该只在对象上调用release。具有retain属性的属性将自动为您进行内存管理,只要您正确处理它们即可。只能通过self.currentColor访问它们。根据您创建颜色对象的方式,您可能会或可能不会使用release,但是您的总是应该在您的dealloc方法中将属性设置为nil。举两个例子:

// If you use this (or some other way to get the color without alloc, copy or retain) 
// then you do not need to do any release 
self.currentColor = UIColor.blackColor; 
self.currentColor = [UIColor colorWithRed:1.0 green:0.5 blue:0.2 alpha:1.0]; 

// On the other hand if you get it like this, you have to release/autorelease the object 
self.currentColor = [[UIColor alloc] initWithRed:1.0 green:0.5 blue:0.2 alpha:1.0]; 
[self.currentColor release]; 
// or better 
self.currentColor = [[[UIColor alloc] initWithRed:1.0 green:0.5 blue:0.2 alpha:1.0] autorelease]; 

// dealloc always the same 
-(void)dealloc{ 
    [currentColor release], currentColor = nil; 
    [super dealloc]; 
} 

这里有两个重要的事实:

  1. 对于每个alloccopyretain你的代码的问题,你必须发出releaseautorelease

  2. 总是使用self.currentColor来访问该属性,而不是currentColor除非取消分配。这里的事情是,当使用self.currentColor时,系统自动添加内存管理代码。只要设置了self.currentColor,它就自动地retain s和release s的对象。只有在最终释放时,您应该直接设置变量,更多信息请参阅this answer on the topic(感谢Flex_Addicted)。

+0

在dealloc方法中调用'self.currentColor = nil;'可能会产生如[release-or-set-to-nil-retained-members]中所建议的问题(http://stackoverflow.com/questions/5358134/release - 或 - 设置为零保留成员)和[MemoryMgmt苹果文档](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html# // apple_ref/doc/uid/TP40004447-SW1) –

+0

谢谢,相当有趣的想法。我会相应地编辑我的帖子。 –

+0

不客气。 –

2

当您使用保留currentColor属性setter你retain该对象,如果你retaincopyalloc内存的对象,你必须将其释放。 -(void)dealloc是做