释放滚动视图内的多个视图控制器的内存 [英] Releasing memory of multiple view controllers inside a scrollview

查看:93
本文介绍了释放滚动视图内的多个视图控制器的内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,该应用程序在滚动视图中加载了许多视图控制器,具体取决于用户在表视图中具有的对象数量.因此,当我在表格视图和滚动视图之间切换时,滚动视图中视图控制器的数量会根据用户在表格视图中拥有多少个对象而变化.

I have an app the loaded many view controllers in a scroll view depending on the number of objects the user has in a tableview. So when I flip between the tableview and the scroll view, the number of view controllers in the scroll view changes according to how many objects the user has in the tableview.

经过一些修改后,我使用Apple的PageControl示例代码中的代码构建了滚动视图,其中包含许多视图控制器.

I use the code in Apple's PageControl sample code to build the scroll view with many view controllers inside it, after some modification of course.

- (void)loadScrollViewWithPage:(int)page 
{
   if (page < 0) return;
   if (page >= kNumberOfPages) return;

   // replace the placeholder if necessary
   MainViewController *countdownController = [viewControllers objectAtIndex:page];
   if ((NSNull *)countdownController == [NSNull null]) 
   {

      id occasion = [eventsArray objectAtIndex:page];

      countdownController = [[MainViewController alloc] initWithPageNumber:page];
      [countdownController setOccasion:occasion];

      [viewControllers replaceObjectAtIndex:page withObject:countdownController];


      [countdownController release];

    }

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

}

问题是,即使我没有添加任何新对象(当然会导致内存问题),当我在表视图和滚动视图之间切换时,活动视图控制器(此处为MainViewController)的数量仍在不断增加

The problem is the number of living view controllers (MainViewController here) keeps increasing when I flip between the table view and the scroll view (according to Instruments) even though I didn't add any new objects which causes memory problems of course.

我在滚动视图的viewWillDisappear中尝试了很多事情,例如:

I tried so many things in viewWillDisappear of the scroll view like:

- (void) viewWillDisappear:(BOOL)animated
{


    //test unloading all views
    //Remove all subviews
    [[scrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

    //[[scrollView subviews] makeObjectsPerformSelector:@selector(release)];


    //[viewControllers removeAllObjects];
    for (unsigned m = 0; m < [viewControllers count]; m++)
    {
     //[[viewControllers objectAtIndex:m] makeObjectsPerformSelector:@selector(release)];

      [viewControllers removeObjectAtIndex:m];
    }
 }

但是没有用. 这是该应用程序工作方式的记录youtube.com/watch?v=5W8v_smZSog

But it didn't work. Here is a recording of how the app works youtube.com/watch?v=5W8v_smZSog

这是滚动视图的viewWillAppear方法:

And this is the viewWillAppear method of the scroll view:

- (void)viewWillAppear:(BOOL)animated
{

    eventsArray = [[NSMutableArray alloc] init];

    kNumberOfPages = [self.dataModel occasionCount];

    //update the eventsArray from the dataModel
    //Fill in the events Array with occasions form the data model
    for (unsigned r = 0; r < kNumberOfPages; r++)
    {
        Occasion* occasion = [self.dataModel occasionAtIndex:r];
        [eventsArray insertObject:occasion atIndex:r];
    }

     // view controllers are created lazily
     // in the meantime, load the array with placeholders which will be replaced on   demand
    NSMutableArray *controllers = [[NSMutableArray alloc] init];
    for (unsigned i = 0; i < kNumberOfPages; i++)
    {
        [controllers addObject:[NSNull null]];
     }

    self.viewControllers = controllers;
    [controllers release];

    // a page is the width of the scroll view
    scrollView.pagingEnabled = YES;
    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages,        scrollView.frame.size.height);
    scrollView.showsHorizontalScrollIndicator = NO;
    scrollView.showsVerticalScrollIndicator = NO;
    scrollView.scrollsToTop = NO;
    scrollView.delegate = self;

    pageControl.numberOfPages = kNumberOfPages;
    pageControl.currentPage = currentPage;

    [self loadScrollViewWithPage:0];
    [self loadScrollViewWithPage:1];
}

更新:乐器的视频录制 http://www.youtube.com /watch?v = u1Rd2clvMQE& feature = youtube_gdata_player

UPDATE: Video recording of Instruments http://www.youtube.com/watch?v=u1Rd2clvMQE&feature=youtube_gdata_player

和显示负责呼叫者的屏幕截图:

And a screen shot showing the responsible caller:

谢谢.

推荐答案

如果您不想使用UIPageViewController(请阅读我的其他答案),这是给您的.

This is for you if you don't want to use UIPageViewController (read my other answer).

该示例项目被设计用于恒定数量的页面(kNumberOfPages). scrollview内容的大小和视图控制器数组的大小取决于页面数.示例代码在awakeFromNib中进行了设置,该过程仅被调用一次.

The sample project is designed for a constant number of pages (kNumberOfPages). The scrollview content size and the size of the view controller array depends on the number of pages. The sample code set this up in awakeFromNib, which is called only once.

因此,为了使其动态化,您可以在页数更改时重新创建整个ContentController.您只需要为页数添加一个属性即可.

So in order to make this dynamic you could recreate the whole ContentController when the number of pages changes. You just need to add a property for the number of pages.

另一种选择是在页数更改时重置滚动视图和视图控制器阵列.

The other option would be to reset the scrollview and view controller array when the number of pages changes.

我假设您已经为事件定义了一个属性:

I'm assuming you have defined a property for the events:

@property(nonatomic,retain) NSArray* eventsArray;

然后您可以添加如下的setter方法:

You could then add a setter method like this:

-(void)setEventsArray:(NSArray *)eventsArray
{
    if (eventsArray != _eventsArray) {
        [_eventsArray release];
        _eventsArray = [eventsArray retain];
        NSUInteger eventCount = [eventsArray count];
        //reset scrollview contentSize
        scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * eventCount, scrollView.frame.size.height);

        // reset content offset to zero
        scrollView.contentOffset = CGPointZero;

        //remove all subviews
        [[scrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

        pageControl.numberOfPages = eventCount;

        // reset viewcontroller array
        NSMutableArray *controllers = [[NSMutableArray alloc] init];
        for (unsigned i = 0; i < eventCount; i++)
        {
            [controllers addObject:[NSNull null]];
        }
        self.viewControllers = controllers;
        [controllers release];

        [self loadScrollViewWithPage:0];
        [self loadScrollViewWithPage:1];
    }
}

您在用户切换到滚动视图时从表视图控制器调用此方法.

You call this method from the table view controller at the time when the user switches to the scroll view.

这篇关于释放滚动视图内的多个视图控制器的内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆