2011-10-18 119 views
0

我在我的目标C代码中的内存泄漏有点麻烦。任何人都可以看一看,让我知道他们在想什么?iOS的NSMutableArray内存泄漏

NSStringArray.h

@interface NSStringArray : NSObject { 

NSMutableArray *realArray; 

} 

@property (nonatomic, assign) NSMutableArray *realArray; 

-(id)init; 
-(void)dealloc; 
@end 

NSStringArray.m

#import "NSStringArray.h" 


@implementation NSStringArray 

@synthesize realArray; 

-(id)init { 

self = [super init]; 
if (self != nil) { 
    realArray = [[[NSMutableArray alloc] init] retain]; 
} 
return self; 
} 

-(void)dealloc { 
[realArray release]; 
realArray = nil; 
[super dealloc]; 
} 

Factory.m

+(NSStringArray *)getFields:(NSString *)line { 
//Divides the lines into input fields using "," as the separator. 
//Returns the separate fields from a given line. Strips out quotes & carriage returns. 

line = [line stringByReplacingOccurrencesOfString:@"\"" withString:@""]; 
line = [line stringByReplacingOccurrencesOfString:@"\r" withString:@""]; 

NSStringArray *fields = [[NSStringArray alloc] init]; 

for (NSString *field in [line componentsSeparatedByString:@","]) { 
    [fields.realArray addObject:field]; 
    [field release];  
} 

return [fields autorelease]; 
} 

泄漏工具说,当字段被分配发生泄漏,当我将字段字符串添加到字段数组。

另外,这个函数正在调用我正在解析的文件的每一行。

任何提示将有所帮助。

谢谢!

回答

3

在这段代码中,你打破了内存管理规则。

for (NSString *field in [line componentsSeparatedByString:@","]) { 
    [fields.realArray addObject:field]; 
    [field release];  
} 

您不拥有field指向的对象,因此您不得释放它。

你有过度发布的领域,所以释放它的最后一个对象(在你的情况下的autorelease池)释放一个已经dealloc'd的对象。

+0

这就是问题所在!非常感谢! –

4

这行做了双重保留:

realArray = [[[NSMutableArray alloc] init] retain]; 

它足够

realArray = [[NSMutableArray alloc] init]; 
+0

这就是我的想法,但是当我取出保留应用程序与EXEC_BAD_ACCESS崩溃。 –

+1

@Erik Rodriguez:那你在其他地方有问题。 – Chuck

+1

这是正确的(+1),但请参阅我的答案,以了解为什么当您留出保留时发生崩溃。 – JeremyP

1

the docs

的分配消息做其他重要的事情除了分配 内存:

  • 它将对象的保留计数设置为1(如“内存管理工作原理”中所述)。

因此,您不需要保留刚刚分配的内容。

+0

这就是我的想法,但是当我取出保留时,应用程序会与EXEC_BAD_ACCESS一起崩溃。它看起来像autorelease池发布时是崩溃。 –

+0

这是因为你正在释放你不应该的东西。请阅读@ JeremyP的回答,然后阅读[内存管理规则](http://tinyurl.com/6ktdglb)。 – Caleb

1

添加到Felz上面的答案。分配阵列

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

时,因为你已经创建了一个属性阵列,因此最好使用使用self.realArray“自我

1

你也可以利用属性的客观C到使 更清晰高效的代码:

NSStringArray。^ h

@interface NSStringArray : NSObject { 
} 
@property (nonatomic, retain) NSMutableArray *realArray; 
@end 

NSStringArray.m

#import "NSStringArray.h" 

@implementation NSStringArray 

@synthesize realArray = _realArray; 

-(id)init { 

self = [super init]; 
if (self) { 
    self.realArray = [NSMutableArray array]; 
} 
return self; 
} 

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

现在,随着属性的修改retain realArray您可以使用 [NSMutableArray array]返回一个自动释放的可变数组。

保留属性自己管理保留/释放的东西。

您不需要使用realArray = nil;行。您已经取消分配 的财产。

希望这可以帮助。

+0

非常好的建议!我对Objective-C仍然很陌生,任何最佳实践都非常受欢迎!谢谢! –