views:

29

answers:

1

Hi there.

I am building a scrollview which swipes through 100 images of houses. It works. But.... For every image viewed the allocated memory inscreases by 2.5 MB. In the end the app crashed because it ran out of memory.

Even if I use the same image as specified in the code below, I run out of memory because of the memory allocations.

I thought that NSMutableArray would release my image (since the retain count gets to zero) when replaced with another object.

What is keeping my images from unloading? How do I unload images?

CodeFragment:

/*!
    @method     
    @abstract   Loads & places an house image.
    @discussion Loads & places an house image and places it on the page at the proper location.
*/
- (void)loadScrollViewWithPage:(int)page {
    if (page < 0) return;
    if (page >= [fetchedObjects count]) return;

    // replace the placeholder if necessary
    [self setSelectedMiniature:[fetchedObjects objectAtIndex:page]];
    NSString *imageLocation = [selectedMiniature image];

    houseImageView = [imageViewArray objectAtIndex:page];
    if ((NSNull *)houseImageView == [NSNull null]) {
        // Use imageWithContentsOfFile: bacause imageNamed: is cached.
        UIImage *houseImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"miniature91.jpg", imageLocation] ofType:nil]];

        houseImageView = [[UIImageView alloc] initWithImage:houseImage];
        [imageViewArray replaceObjectAtIndex:page withObject:houseImageView];
        [houseImageView release];
    }

    // add the controller's view to the scroll view
    if (nil == houseImageView.superview) {
        CGRect frame = scrollView.frame;
        frame.origin.x = frame.size.width * page;
        frame.origin.y = 0;
        houseImageView.frame = frame;
        [scrollView addSubview:houseImageView];
    }

}

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    // Switch the indicator when more than 50% of the previous/next page is visible
    CGFloat pageWidth = scrollView.frame.size.width;
    int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;

    // load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
    [self clearPage:page - 2];  
    [self loadScrollViewWithPage:page - 1];
    [self loadScrollViewWithPage:page];
    [self loadScrollViewWithPage:page + 1];
    [self clearPage:page + 2];  

    // A possible optimization would be to unload the views+controllers which are no longer visible 
//  for (int i = 0; i < [imageArray count]; i++) {   
//      if (i < (page - 1) || i > (page + 1)) {                   
//          [imageArray replaceObjectAtIndex:i withObject:[NSNull null]];               
//      } 
//  } 

}

- (void)clearPage:(int)page {
    if (page < 0) return;
    if (page >= [fetchedObjects count]) return;
    [imageViewArray replaceObjectAtIndex:page withObject:[NSNull null]];                 
}

// At the begin of scroll dragging, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    [self swapSliderForRatingView];
    //[self showInfo:YES];
}

// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    [self swapSliderForRatingView];
    [self updateMiniatureInfo];
    //[self showInfo:NO];
}
A: 

After quickly looking at your code, I can see that you're managing an array of image views and presumably removing them at appropriate times, but I haven't spotted where you are removing the image views from the scroll view they're getting stuffed into.

So long as those views are part of a subview list, they're not going to be released. This may be why you're running into memory troubles.

MrO
You were right !!! That fixed the issue. I should have realised that the views were retained by the scrollView. Stupid but learnfull mistake. Thanx
P5ycH0