Padin215
Padin215

Reputation: 7484

when i release an NSMutableArray that i allocate and initiate, my code breaks

with this code, i want to add an image at the place the user taps. i want to add a new one for each tap.

-(void) foundDoubleTap:(UITapGestureRecognizer *) recognizer
{       
    UIView *piece = recognizer.view;
    CGPoint locationInView = [recognizer locationInView:piece];

    UIImageView *testPoint = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"inner-circle.png"]];
    testPoint.frame = CGRectMake(0, 0, 20, 20);
    testPoint.center = CGPointMake(locationInView.x, locationInView.y);
    [self.imageView addSubview:testPoint];

    NSMutableArray *tempTestPointArray = [[NSMutableArray alloc] initWithArray:testPointArray];
    [tempTestPointArray addObject:testPoint];
    testPointArray = tempTestPointArray;

    NSLog(@"testPointArray: %@", testPointArray);

    CGRect myRect = CGRectMake((testPoint.center.x + 12), (testPoint.center.y + 12), 10, 10);

    UILabel *myLabel = [[UILabel alloc] initWithFrame:myRect];
    myLabel.text = [NSString stringWithFormat:@"Point %d", [testPointArray count]];
    myLabel.font = [UIFont fontWithName:@"Trebuchet MS" size:10];
    [myLabel sizeToFit];
    [imageView addSubview:myLabel];
    [myLabel release];

    [testPoint release];
    //[tempTestPointArray release];
}

why is it that when i release tempTestPointArray, my code breaks when i implement a second tap? it crashes on:

NSMutableArray *tempTestPointArray = [[NSMutableArray alloc] initWithArray:testPointArray];

when i comment out the release for it, the Analyzer does not flag it as a leak. what happened to the rule, if you alloc/init it, you have to release it?

EDIT: adding .h file

.h file:

@interface TestPointMapViewController : UIViewController <UIScrollViewDelegate, UITextFieldDelegate>
{
    //other code
    NSArray *testPointArray;
}
//other code
@property (nonatomic, retain) NSArray *testPointArray;
//other code
@end

and then @synthesize testPointArray in .m file.

Upvotes: 1

Views: 81

Answers (1)

logancautrell
logancautrell

Reputation: 8772

Your testPointArray is not assigning to a property, it is a plain ivar. Doing the line

testPointArray = tempTestPointArray;

Is leaking whatever is previously in testPointArray. Declare testPointArray as a retained property and change to.

self.testPointArray = tempTestPointArray;

Then keep the [tempTestPointArray release];

EDIT:

So the reason why this code is failing has to do with the magic of properties. The following code is equivalent.

self.testPointArray = tempTestPointArray;
[self setTestPointArray:tempTestPointArray];

When you do the @sythesize testPointArray; it is generating a setter method similar to this:

- (void)setTestPointArray:(NSMutableArray *)array {
    id temp = testPointArray;
    testPointArray = [array retain];
    [temp release];
}

So when you don't use the property notation self.testPointArray you are not retaining the variable correctly. You are also losing a reference to a retained object, which is now a leak.

That make sense? If not please review this.

http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/objectiveC/Chapters/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17-SW1

Upvotes: 3

Related Questions