views:

37

answers:

3

I'd like some assistance to properly remove subviews from a scrollview, to reduce memory usage. Every time the user scrolls, I ask to grab page, page -1 and page+1 to get the views loaded in the scrollview.

Now my issue is that if there's ten views side by side, when you reach the tenth view, all the previous 9 views are still subviews in the scrollview and in memory. I'd like to reverse load these views as well. Here's what I have so far:

- (void)loadScrollViewWithPage:(int)page {
    if (page < 0) return;
    if (page >= [self favouritesCount]) return;
    // replace the placeholder if necessary
    MyObject *myObj = (MyObj *)[fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:page inSection:0]];
    MyView *controller = [viewControllers objectAtIndex:page];
    if ((NSNull *)controller == [NSNull null]) {
        controller = [[MyView alloc] initWithObject:myObj];
        controller.delegate = self;
        [viewControllers replaceObjectAtIndex:page withObject:controller];
    }
    // add the controller's view to the scroll view
    if (nil == controller.superview) {
        CGRect frame = scrollView.frame;
        frame.origin.x = frame.size.width * page;
        frame.origin.y = 0;
        controller.frame = frame;
        [scrollView addSubview:controller];
    }
}

Now I have tried something like:

if (page > 2) {
    [(UIView *)[[scrollView subviews] objectAtIndex:(page - 2)] removeFromSuperview];
}

But that just crashes it. It's probably a simple solution, so help is appreciated :)

A: 

Did you increment the pageCount?

You can try with this as well:

MyView *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller != [NSNull null]) {
   [controller removeFromSuperView];
}

Some notes for naming convention: MyView *controller does not make sense. If MyView is subclass of UIView, you should only name if MyView *view

vodkhang
Thanks, will try that.Yes, I did not in fact name it MyView - just used the name for sharing purposes, because the class name was too telling and the project's under NDA.
Canada Dev
Doesn't seem to do the job? Anyone else?
Canada Dev
Hum, that sounds strange. Something wrong with the view. I think I need to view more codes
vodkhang
A: 

I think if I were you, I would just add "loadData" and "releaseData" methods on my views, and call those when they're coming in and out of view. Sure, you'll still have the view classes loaded, but in those methods you can get rid of (and re-load) the more heavyweight sub-objects that those views contain.

Good luck,
Blake.

bwinton
A: 

I think your problem is in the solution you posted:

[(UIView *)[[scrollView subviews] objectAtIndex:(page - 2)] removeFromSuperview];

If you remove the previously loaded views, you always have 2 views loaded, so you cant access page-2 because you dont have page-2 views loaded in the scrollview. (think for example when page is 5, you will access view 3 from scrollview)

You should consider 2 things:

1.- Use [[[viewControllers objectAtIndex:page-2] view] removeFromSuperview]; instead (take a look that here i use viewcontrollers instead of scroll.subviews)

2.- Remove the view from the viewcontrollers array , because just removing the view from the scroll will not release the view from memory (its retained by the array). For this, use something like: [viewControllers replaceObjectAtIndex:page-2 withObject:[NSNull null]];

Angel García Olloqui
Sorry, i didnt realized that your viewcontrollers array is a views array actually. So, dont use [[[viewControllers objectAtIndex:page-2] view] removeFromSuperview]; use [[viewControllers objectAtIndex:page-2] removeFromSuperview]; instead
Angel García Olloqui