views:

136

answers:

2

the image that is being displayed in this code is leaking but I cant figure out how. What I have a tableview that displays images to be displayed. Each time a user selects an image, it should remove the old image, download a new one, then add it to the scroll view. But the old image is not being released and I cant figure out why...

-(void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [imageView removeFromSuperview];
    self.imageView = nil;
    NSUInteger row = [indexPath row];

    NSString *tempC = [[NSString alloc]initWithFormat:@"http://www.website.com/%@_0001.jpg",[pdfNamesFinalArray objectAtIndex:row] ];
    chartFileName = tempC;
    pdfName = [pdfNamesFinalArray objectAtIndex:row];

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                         NSUserDomainMask, YES);
    NSString *docsPath = [paths objectAtIndex:0];
    NSString *tempString = [[[NSString alloc]initWithFormat:@"%@/%@.jpg",docsPath,pdfName]autorelease];
    NSData *data = [NSData dataWithContentsOfFile:tempString];

    if (data != NULL){
        self.imageView = nil;
        [imageView removeFromSuperview];
        self.imageView = nil;
        UIImageView *tempImage = [[[UIImageView alloc]initWithImage:[UIImage imageWithData:data]]autorelease];
        self.imageView = tempImage;
        [data release];
        scrollView.contentSize = CGSizeMake(imageView.frame.size.width , imageView.frame.size.height);
        scrollView.maximumZoomScale = 1;
        scrollView.minimumZoomScale = .6;

        scrollView.clipsToBounds = YES;
        scrollView.delegate = self;

        [scrollView addSubview:imageView];
        scrollView.zoomScale = .37;

    }

    else {
        [data release];
        self.imageView = nil;
        [imageView removeFromSuperview];
        self.imageView = nil;
        activityIndicator.hidden = NO;
        getChartsButton.enabled = NO;
        chartListButton.enabled = NO;
        saveChartButton.enabled = NO;
        [NSThread detachNewThreadSelector:@selector(downloadImages) toTarget:self withObject:nil];



    }
chartPanel.hidden = YES;



}

-(void) downloadImages {

    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    self.imageView = nil;
    [imageView removeFromSuperview];
    NSURL *url = [[[NSURL alloc]initWithString:chartFileName]autorelease];
    NSData *data = [NSData dataWithContentsOfURL:url];

    UIImageView *tempImage = [[[UIImageView alloc]initWithImage:[UIImage imageWithData:data]]autorelease];
    self.imageView = tempImage;
    tempImage = nil;

    scrollView.contentSize = CGSizeMake(imageView.frame.size.width , imageView.frame.size.height);
    scrollView.maximumZoomScale = 1;
    scrollView.minimumZoomScale = .37;
    scrollView.clipsToBounds = YES;
    scrollView.delegate = self;
    [scrollView addSubview:imageView];
    scrollView.zoomScale = .6;

    activityIndicator.hidden = YES;
    getChartsButton.enabled = YES;
    chartListButton.enabled = YES;
    saveChartButton.enabled = YES;
    [pool drain];
    [pool release];
}
+7  A: 

This looks wrong:

self.imageView = nil;
[imageView removeFromSuperview];

You are setting imageView to nil before removing it from the superview, so the 2nd statement is really just [nil removeFromSuperview];, which isn't going to do anything.

David Gelhar
+1 because it's the right answer. David Gelhar? The BlitzMail guy?
quixoto
+3  A: 

I think the leak is what David Gelhar said, but I just wanted to add that you shouldn't access UI stuff from threads other than the main thread (so for instance, don't do [imageView removeFromSuperview] under a separate thread). This can cause very odd problems, including mysterious leaks. Try putting all that stuff in a separate method on the main thread that you call with [self performSelectorOnMainThread:] and see if it still leaks.

Also (although this wouldn't cause the leak), [pool drain] releases the autorelease pool, so you shouldn't invoke [pool release] after it--it might release the pool on the main thread, possibly causing a crash somewhere down the line (since you could over-release the pool).

eman