保留/复制自动释放的对象

时间:2011-06-20 20:18:26

标签: iphone objective-c memory-management

我想确保我在这里正确理解内存管理。有没有什么特别的理由在这里使用其中一个assignCurrentDate方法? 而且,所有这些都导致没有内存泄漏,对吗?

在.h中我们有:

NSDate *currentDate1;
NSDate *currentDate2;
NSDate *currentDate3;
NSDate *currentDate3; 
//and 
@property (nonatomic, retain) NSDate *currentDate1;
@property (nonatomic, retain) NSDate *currentDate2;
@property (nonatomic, retain) NSDate *currentDate3;
@property (nonatomic, retain) NSDate *currentDate4;
<。>中的

-(void) assignCurrentDate1
{
currentDate1 = [[NSDate date]retain];
//[NSDate date] is autoreleased
}

-(void) assignCurrentDate2
{
currentDate2 = [[NSDate date]copy]; 
}

-(void) assignCurrentDate3
{
self.currentDate3 = [NSDate date];
}

-(void) assignCurrentDate4
{
currentDate4 = [[NSDate alloc]init];
//[[NSDate alloc]init] is not autoreleased.
}

-(IBAction) printDate
{
NSLog ("%@", currentDate1);
NSLog ("%@", currentDate2);
NSLog ("%@", currentDate3);
NSLog ("%@", currentDate4);
}

- (void)dealloc
{
[currentDate1 release];
[currentDate2 release];
[currentDate3 release];
[currentDate4 release];
[super dealloc];
}

2 个答案:

答案 0 :(得分:6)

iOS内存管理的经验法则是:

  

对于每个allocretaincopynew,您必须拥有相应的releaseautorelease

你实际上在几个地方泄漏了。 在标题中,您retain日期对象,然后在dealloc方法中释放它们。那是正确的。但是,在assignDate方法中,您无法释放副本或保留日期。虽然[NSDate date]是自动释放的,但您自己会保留并复制它们。

没有理由使用您的assignCurrentDate方法。您可以在init方法中执行以下操作:

self.currentDate1 = [NSDate date];

就是这样。

编辑(好的,那是不是它。)

正如吉姆在评论中指出的那样:

标题中的保留表示这些属性的合成setter将保留分配给它们的对象。但是如果你看一下assign *方法,你会发现只有assignCurrentDate3实际上使用了该属性。其余部分直接分配给ivar,绕过合成的setter,因此在分配时不会保留它们。

答案 1 :(得分:2)

是的,您正确了解内存管理。假设您不多次调用这些方法,那些泄漏都没有。第二个在内存使用方面效率较低,因为创建了NSDate的两个实例。实际上,它们在性能方面略有不同,但除非你将它们放入紧密的循环中,否则它们并没有显着的变化。

在程序设计方面,您不希望编写这样的代码,因为如果您多次调用1,2或4次,最初分配的实例将会泄漏。如果您确定这不是问题(例如,如果您在viewDidLoad中分配并在viewDidUnload中发布),那么您可以安全地使用任何这些样式,但如果您不确定在这种情况下,您需要在分配之前通过释放来保护您的任务,或者您应该使用第三种基于属性的方法,它为您执行此操作。