0
votes

I ran analyze on my 1st iPhone app, and I see a few potential memory leaks. The app itself works fine on the simulator. I would like to do the right thing and clear the potential memory leaks, but some are quite puzzling. Maybe someone could help me here?

Thanks in advance.

Pier.

Error 1) The Analyzer says "Potential leak of an object stored in tempDate and tempAns"

#import "Answer.h"

@implementation Answer
@synthesize answerTiming; 
@synthesize xPosition; 
@synthesize earlyOrLate; 
@synthesize hit; 

+ (Answer *) createAnswerWithTiming :(NSDate *)paramTiming andXPosition :(float) xPosition
{
NSDate * tempDate = [[NSDate alloc] initWithTimeInterval:0 sinceDate:paramTiming];
Answer * tempAns = [[Answer alloc] init ];
[tempAns setAnswerTiming:tempDate];
[tempDate release];
[tempAns setXPosition:xPosition]; 
[tempAns setEarlyOrLate:0];
[tempAns setHit:false];

return tempAns; 
}


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

@end

Error 2) Analyzer says (see below)

- (void)viewDidLoad
{
[super viewDidLoad];

   ........
   ...

UIImage * perfectImage = [UIImage imageNamed: @"perfect.png"];
self.perfectImageView2 = [[UIImageView alloc]initWithImage:perfectImage]; 

// method returns an objective C content with a +1 retain count

[self.perfectImageView2 setFrame:CGRectMake(145.0f,
                                            150.0f,
                                            self.perfectImageView2.image.size.width,
                                            self.perfectImageView2.image.size.height)];

self.view.backgroundColor = [UIColor whiteColor];

UIImage * levelUpImage = [UIImage imageNamed:@"levelup.png"];
self.levelUpImageView = [[UIImageView alloc] initWithImage:levelUpImage];
[self.levelUpImageView setFrame:CGRectMake(100.0f,
                                            400.0f,
                                            self.levelUpImageView.image.size.width,
                                            self.levelUpImageView.image.size.height)];

//object leaked, allocated object is not referenced later in this execution path and has a retain count of +1

self.view.backgroundColor = [UIColor whiteColor];
}

Error 3)

- (NSMutableArray *) generateQuestionTapAnswers:(NSString *) answersString withFirstBeat:    (NSDate *) firstBeatTime
{
NSArray * notesToDraw = [answersString componentsSeparatedByCharactersInSet: [NSCharacterSet characterSetWithCharactersInString: @" "]];

float noteValueOffset = 0.0; 

NSMutableArray * answerArray = [[NSMutableArray alloc] init ];

// Method returns an objective C object with a +1 retain count

for (int i=1; i < notesToDraw.count; i++) // i = 0 is the time signature
{
 .....
}
return answerArray;

// Object returned to caller as an owning reference (single retain count transferred to caller) // Object leaked: Object allocated and stored into answerArray is returned from a method whose name generateQuestionTapAnswers does not start with copy, mutableCopy }

1

1 Answers

1
votes

Regarding your first and third warnings, the compiler will assume that you'll be creating an object in "a method whose name begins with alloc, new, copy, or mutableCopy" (see Advanced Memory Management Programming Guide). So, if you're returning a +1 object, make sure your method name begins with one of those four prefixes. If you create a +1 object without one of those prefixes, it won't be happy. So, for error #1, if you rename that method to be something like newAnswerWithTiming, that warning should go away. (If the calling method doesn't clean up after them, though, the warning will just be shifted to that routine, but let's take it one step at a time.)

Likewise for error #3, if you rename that method to be something like newAnswerArrayFromQuestionTapAnswers (or whatever ... I'm not sure if I understand your method name ... just make sure it starts with new), you'll similarly eliminate that warning. In both cases, just make sure to release it at the appropriate point because whomever called these two respective methods now "owns" those objects and is responsible for their cleanup.

As an aside, you don't need to do [self release] in your dealloc in your discussion of error #1. (Frankly, I'm surprised it doesn't generate an error.) You don't need it because if self wasn't already at retainCount of zero, you never would have gotten to dealloc in the first place.

Regarding error #2, how are the properties perfectImageView2 and levelUpImageView defined? If retain or strong, you're creating something with a +2 retainCount, and you probably want to add an autorelease after the alloc/init.