2010-02-26 95 views
1

Xcode Instruments声称下面的代码导致内存泄漏。据我了解,分配财产时,发生以下情况:
*旧值会被自动释放
*新的值会保留
*新的价值显然是
赋予它的头脑,怎么来的我内存泄漏,我该如何解决?iPhone NSMutableArray内存泄漏

“TestProjectViewController.h”:

#import <UIKit/UIKit.h> 

@interface TestProjectViewController : UIViewController { 
    NSMutableArray* array; 
} 

@property (nonatomic, retain) NSMutableArray* array; 

@end 

“TestProjectViewController.m”:

#import "TestProjectViewController.h" 

@implementation TestProjectViewController 

@synthesize array; 

- (void)applicationDidFinishLaunching:(UIApplication *)application {  
    for(int i = 0; i < 5; i++) { 
     self.array = [[NSMutableArray alloc] init]; 
     [self.array addObject:@"Hello world #1"]; 
     [self.array addObject:@"Hello world #2"]; 
    } 
} 

回答

5
self.array = [[NSMutableArray alloc] init]; 

在这里,你留住新的数组对象两次 - 当setter方法分配它,然后。其中一个应该解决这个问题:

self.array = [[[NSMutableArray alloc] init] autorelease]; 
// or 
self.array = [NSMutableArray arrayWithCapacity:someNumber]; 

也不要忘了在dealloc方法中释放你的数组。

+0

当我需要手动释放阵列时,它是属性为“retain”的属性吗? – 2010-02-26 15:43:52

+1

绝对是。你也可以通过调用'self.array = nil;' – kubi 2010-02-26 15:45:59

+0

来释放数组,因为属性“retain”属性定义了相应setter方法的行为 - 你递增对象保留count,所以必须在那之后释放该对象。如果您更改属性值,则旧对象将自动释放。如果你销毁你的对象,你必须释放所有(以前保留的)其成员。如果需要,可以在dealloc方法中调用'self.array = nil'而不是显式释放 – Vladimir 2010-02-26 15:51:25

1

每次通过循环,你都会得到一个新的数组alloc。每个数组以1的引用次数开始,分配给属性将其增加到2.您需要release这些数组,以便该属性是对象的唯一“所有者”。

例如,你可以这样做:

- (void)applicationDidFinishLaunching:(UIApplication *)application {  
    for(int i = 0; i < 5; i++) { 
     self.array = [[NSMutableArray alloc] init]; 
     [self.array addObject:@"Hello world #1"]; 
     [self.array addObject:@"Hello world #2"]; 
     [self.array release]; 
    } 
} 

或做到这一点:

- (void)applicationDidFinishLaunching:(UIApplication *)application {  
    for(int i = 0; i < 5; i++) { 
     self.array = [[[NSMutableArray alloc] init] autorelease]; 
     [self.array addObject:@"Hello world #1"]; 
     [self.array addObject:@"Hello world #2"]; 
    } 
} 
0

这种方法的泄漏,因为alloc/init有一个隐含的保留,然后属性保留一个更多的时间。这会导致每个数组保留两次。您可以在该循环结束时使用autorelease数组或release

作为一个方面说明,为什么你在循环中指定一个属性?只有最后一个数组将保留在该属性中。相反,您可以使用局部变量并仅分配最后一个数组:

- (void)applicationDidFinishLaunching:(UIApplication *)application { 
    NSMutableArray *tempArray = nil; 

    for(int i = 0; i < 5; i++) { 
     tempArray = [[[NSMutableArray alloc] init] autorelease]; 
     [tempArray addObject:@"Hello world #1"]; 
     [tempArray addObject:@"Hello world #2"]; 
    } 

    self.array = tempArray; 
} 
1

您正在初始化循环内的数组。那不需要你至少将数组的值赋给另一个对象。在这种情况下,你也必须在循环中释放它。你没有释放内存。由于您为阵列分配了内存,因此您也应该释放内存:

- (void)applicationDidFinishLaunching:(UIApplication *)application {  
    self.array = [[NSMutableArray alloc] init];//You just need to initialize the array just once 
    for(int i = 0; i < 5; i++) { 
    [self.array addObject:@"Hello world #1"]; 
    [self.array addObject:@"Hello world #2"]; 
    } 
} 
//Finally its necessary to release the memory when the app quits using the release method 
[self.array release]