开发者

How to release a viewController and his view inside of an NSMutableArray viewControllers?

开发者 https://www.devze.com 2023-02-20 10:45 出处:网络
I have a big problem with my memory management. A actually have a big magazine and every page it is render with his own PageViewController. My code it\'s totally based on PageControl sample of Apple D

I have a big problem with my memory management. A actually have a big magazine and every page it is render with his own PageViewController. My code it's totally based on PageControl sample of Apple Documentation, if you guys have seen sometime.

So, in the viewDidLoad of my "MainViewController" I create a NSMutableArray = self.viewControllers full of NSNull objects. And I call my [self loadScrollViewPage:page]; for my first and second pages. When the user navigate into more pages, I call (from scrollViewDidScroll) more load [self loadScrollViewPage:nextPage]; as the App will be need it. Also I implement a unloadScrollViewPage:page 'cause the magazine is so big, that the memory will be out if I don't.

So, this is my code:

- (void)loadScrollViewPage:(int)pageNumber
{
    if ((pageNumber < 0) || (pageNumber >= [self.viewControllers count]))
        return;

    PageViewController *controller = [self.viewControllers objectAtIndex:pageNumber];
    if ((NSNull *)controller == [NSNull null])
    {
        controller = [[PageViewController alloc] initWithPage:[self.pages objectAtIndex:pageNumber]];
        [self.viewControllers replaceObjectAtIndex:pageNumber withObject:controller];
        [controller release];
    }

    if (controller.view.superview == nil)
    {
        CGRect frame = mainpageScrollView.frame;
        frame.origin.x = 0;
        frame.origin.y = frame.size.height * pageNumber;
        controller.view.frame = frame;
        [mainpageScrollView addSubview:controller.view];
    }
}
- (void)unloadScrollViewPage:(int)pageNumber
{
    if ((pageNumber < 0) || (pageNumber >= [self.viewControllers count]))
        return;

    if ((NSNull *)[self.viewControllers objectAtIndex:pageNumber] != [NSNull null])
    {
        [[[self.viewControllers objectAtIndex:pageNumber] view] removeFromSuperview];
        [self.viewControllers removeObjectAtIndex:pageNumber];
        [self.viewControllers replaceObjectAtIndex:pageNumber withObject:[NSNull null]];
    }
}

The problem is, no matter how many times I call unloadScrollViewPage, the memory still increment size when I call loadScrollViewPage and never decrement with unloadScrollViewPage. So, when the user is going in the 10 page (of 300 pages, lol?) the memory size of my App is of 100Mb and of course, it crash :(

My questions are:

  • Am I releasing memory correctly from my self.viewControllers NSMutableArray?
  • The views of each controller that I put on they superview (the view of MainViewController) will release it when I removeObjectAtIndex:pageNumber from the self.viewControllers? If not, how can I do it? Is this my problem?

Thanks in advanced.

EDIT:

Looks like Firoze Lafeer was right at the beginning, the problem was my UIImage memory management and my views retained. I just manage to removeFromSuperview each UIView. For the images, looks like using [UIImage imageNamed] it implements a cache (that release it when ios wants ¬¬). I just change开发者_开发百科 the way using [UIImage imageWithData:imageData]; which doesn't implements cache and all my objects are happy now. Thanks everybody. :)


Right, when you add each view to the scrollview, the scrollview will retain that view. So you will have to remove each view as you unload each page.

BTW, I think you'll find that the view controllers themselves don't take up very much memory at all. The views are the bigger issue.


The rest of your code looks like it should behave the way you expect it however these two lines might not be right.

    [self.viewControllers removeObjectAtIndex:pageNumber];
    [self.viewControllers replaceObjectAtIndex:pageNumber withObject:[NSNull null]];

The first line is going to remove the object and decrement all the indexes above it by one, so your array will be one smaller. Then you are calling replaceObject at the object that once was one index higher than the object you removed. These two lines of code will decrease the size of your array by one every time it's called until you get an out of bounds exception when you go passed the actual length of the array.You can remove the removeObject line and replaceObject will release that object on it's own while leaving your array the same size.

This probably won't solve your problem though as it will decrement the retain counter the same way. Perhaps it would help to post the code that calls these methods.

0

精彩评论

暂无评论...
验证码 换一张
取 消