Reputation: 145
I'm having a bit of trouble with memory leaks in my objective c code. Could anyone take a look and let me know what they think?
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];
}
The Leaks tool is saying that the leak occurs when fields is allocated, and when I am adding field string to the fields array.
Also, this function is getting called each line of a file that I'm parsing.
Any tips would be helpful.
Thanks!
Upvotes: 0
Views: 1007
Reputation: 83
You could also take advantage of the properties in objective C to make more clear and efficient your code:
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];
}
Now, with the modifier retain
of the property realArray you can use
[NSMutableArray array]
that return an autorelease mutable array.
The retain properties manage the retain/release stuff by themselves.
You don't need to use the realArray = nil;
line. You've already deallocated
the property.
Hope this can help.
Upvotes: 1
Reputation: 28740
Adding to Felz answer above. Use self.realArray when allocating array
self.realArray = [[NSMutableArray alloc] init];
Because you have created a property for the array so it is better to use "self"
Upvotes: 1
Reputation: 86681
In this piece of code, you break the memory management rules.
for (NSString *field in [line componentsSeparatedByString:@","]) {
[fields.realArray addObject:field];
[field release];
}
You do not own the object pointed at by field
so you must not release it.
You have overreleased field so the last object to release it (the autorelease pool in your case) is releasing an already dealloc'd object.
Upvotes: 3
Reputation: 125017
From the docs:
An allocation message does other important things besides allocating memory:
- It sets the object’s retain count to one (as described in “How Memory Management Works”).
Therefore, you don't need to retain something that you've just alloc'ed.
Upvotes: 2
Reputation: 8759
This line does a double retain:
realArray = [[[NSMutableArray alloc] init] retain];
it is enough
realArray = [[NSMutableArray alloc] init];
Upvotes: 4