
Please help! I’ve read the memory management rules, but maybe I’m missing them point somewhere. Instruments is telling me I’ve got leaks on the following code:
NSArray *keys = [NSArray arrayWithObjects:@"text", @"score", @"subCount", nil];
NSArray *objects
= [NSArray arrayWithObjects:sPlateToAdd, [
[[NSNumber alloc] initWithInt:1] autorelease],
[[[NSNumber alloc] initWithInt:1] autorelease],
nil];
NSMutableDictionary *dPlateToAdd
= [NSMutableDictionary dictionaryWithObjects:objects forKeys:keys]; // 93.4%
[self.aFinals addObject:dPlateToAdd]; // 6.6%
the Keys and Objects arrays aren’t being alloc’ed or init’ed, so I dont think I need to release those?
Then the numbers inside Objects are being auto released, so they’re ok aren’t they?
And sPlateToAdd is a string that gets passed into the method this code is in, so I’m not the owner of that, so I don’t need to release it. Or am I?
I’ve got to be doing something wrong somewhere.
The app runs completely fine in the iPad, but is dog slow on an iPhone 3GS, I’m hoping fixing this memory leak might speed it up a little…
This is the method that creates self.aFinals, which is passed a string from a text input. I’ve ommitted some of the lines but self.aFinals doesn’t interact with them
-(id)initWithTerm:(NSString *)thisTerm {
...
...
self.aFinals = [[NSMutableArray alloc] init];
return self;
}
Then I have about 5 nested loops, that call addPlateToFinals 3 times in the middle of all the loops, creating thisPlate, which becomes sPlateToAdd
// replace 1st occurance
NSString *thisPlate = [thisBase
stringByReplacingOccurrencesOfRegex:[NSString stringWithFormat:
@"(^[^%@]+)%@(.*$)",
thisChar,
thisChar]
withString:[NSString stringWithFormat:@"$1%@$2", thisSub]
];
[self addPlateToFinals:thisPlate withSubCount:thisSubCount];
// replace 2nd occurance
thisPlate = [thisBase
stringByReplacingOccurrencesOfRegex:[NSString stringWithFormat:
@"(^[^%@]+%@.*)%@",
thisChar,
thisChar,
thisChar]
withString:[NSString stringWithFormat:@"$1", thisSub]
];
// then it does it again, with slightly different regex
This is the complete method that the leak is coming from:
-(void)addPlateToFinals:(NSString *)sPlateToAdd withSubCount:(NSNumber *)nSubCount {
// plate must be less than 7 characters and great than 2 chars
if (
[sPlateToAdd length] <= [self.nPlateMax intValue] &&
[sPlateToAdd length] >= [self.nPlateMin intValue]
) {
NSMutableArray *aSearchFinals = [self arrayOfFinals];
// add plate if it is not already in the finals array
if(![aSearchFinals containsObject:sPlateToAdd]) {
// filter out results that cannot be converted to valid plates
NSPredicate *potential = [NSPredicate predicateWithFormat: @"SELF MATCHES '^[a-z]{0,3}[0-9]{1,3}[a-z]{0,3}$'"];
NSPredicate *impossible1 = [NSPredicate predicateWithFormat: @"SELF MATCHES '^[a-z]{2}[0-9]{2,3}[a-z]{2}$'"];
NSPredicate *impossible2 = [NSPredicate predicateWithFormat: @"SELF MATCHES '^[a-z][0-9]{3}$'"];
NSPredicate *impossible3 = [NSPredicate predicateWithFormat: @"SELF MATCHES '^[a-z]{2}[0-9]{2}$'"];
NSPredicate *impossible4 = [NSPredicate predicateWithFormat: @"SELF MATCHES '^[0-9]{2}[a-z]{2}$'"];
if(
[potential evaluateWithObject: sPlateToAdd] &&
![impossible1 evaluateWithObject: sPlateToAdd] &&
![impossible2 evaluateWithObject: sPlateToAdd] &&
![impossible3 evaluateWithObject: sPlateToAdd] &&
![impossible4 evaluateWithObject: sPlateToAdd]
){
NSArray *keys = [NSArray arrayWithObjects:@"text", @"score", @"subCount", nil];
NSArray *objects = [NSArray arrayWithObjects:
sPlateToAdd,
[[[NSNumber alloc] initWithInt:1] autorelease],
[[[NSNumber alloc] initWithInt:1] autorelease],
nil
];
NSDictionary *dPlateToAdd = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
[self.aFinals addObject:dPlateToAdd];
}
}
}
}
You should show the entire `addPlateToFinals’ method, sPlateToAdd could be leaking.
Based on the new added code
self.aFinalsis leaking if the property is declared with retain(and I’m %99 it is). Should be:self.aFinals = [[[NSMutableArray alloc] init] autorelease]or even better:
self.aFinals = [NSMutableArray array]