2010-11-30 115 views
3

为什么会泄漏?这个Objective-C代码为什么会泄漏内存?

arrayOfPerformances是合成的NSMutableArray,(nonatomic, retain)属性。

currentPerformanceObjectPerformance *,(nonatomic, retain)合成的属性。

Performance是一个自定义类

if(self.arrayOfPerformances == nil) 
    { 
     self.arrayOfPerformances = [[NSMutableArray alloc]init]; 
    } 

    [self.arrayOfPerformances addObject:currentPerformanceObject]; 
    [currentPerformanceObject release]; 
    currentPerformanceObject = nil; 

回答

11

您正在创建一个新的数组在这条线的同时保留它,因为你调用与点号一个(retain)的属性设置:

// Your property 
@property (nonatomic, retain) NSMutableArray *arrayOfPerformances; 

// The offending code 
self.arrayOfPerformances = [[NSMutableArray alloc]init]; 

因此,本地创建的阵列泄漏,因为您不释放它。你应该自动释放该数组,或者创建一个临时局部变量,分配,然后释放局部变量,就像这样:

// Either this 
self.arrayOfPerformances = [[[NSMutableArray alloc] init] autorelease]; 

// Or this (props Nick Forge, does the same as above) 
self.arrayOfPerformances = [NSMutableArray array]; 

// Or this 
NSMutableArray *newArray = [[NSMutableArray alloc] init]; 
self.arrayOfPerformances = newArray; 
[newArray release]; 
+1

尼克说什么;使用`[NSMutableArray数组]` – bbum 2010-11-30 03:36:00

+0

哇,那个制定者真的搞砸了我的想法。我梳理了我的代码几个小时,试图找出泄漏的位置,并最终隔离了代码,并且无法弄清楚我的生活出了什么问题。太感谢了! – Mausimo 2010-11-30 03:41:30

4

如果您.arrayOfPerformances物业从来没有公布过(它通常会在-dealloc公布),比数组本身,加上数组中的任何对象都会在处理这个对象时泄漏。

你需要在你-dealloc释放两个属性:

- (void)dealloc 
{ 
    ... other deallocs 
    self.arrayOfPerformances = nil; 
    self.currentPerformanceObject = nil; 
    [super dealloc]; 
} 

此外,作为@BoltClock已经指出的那样,你需要释放或自动释放你的NSMutableArray。要做到这一点,最好的办法就是使用自动释放的方法来初始化它:

self.arrayOfPerformances = [NSMutableArray array]; 

而且,你不需要释放你currentPerformanceObject,你应该只设置属性为nil,因为retain编辑属性设置为nil会为您发布。您的代码可能应该是这个样子:

if (self.arrayOfPerformances == nil) { 
    self.arrayOfPerformances = [NSMutableArray array]; 
} 
[self.arrayOfPerformances addObject:self.currentPerformanceObject]; 
self.currentPerformanceObject = nil; 
1

此行是罪魁祸首:

self.arrayOfPerformances = [[NSMutableArray alloc]init]; 

保留计数为1的分配/初始化后。通过arrayOfPerformances属性设置器设置值会再次增加保留计数(因为它是一个保留属性)。