Reputation: 7484
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
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.
Upvotes: 3