ios - 在 ScrollView 中释放多个 View Controller 的内存

标签 ios memory uiviewcontroller uitableview scrollview

我有一个应用程序在 ScrollView 中加载了许多 View Controller ,具体取决于用户在表格 View 中拥有的对象数量。因此,当我在 tableview 和 ScrollView 之间切换时, ScrollView 中的 View Controller 数量会根据用户在 tableview 中拥有的对象数量而变化。

当然,经过一些修改,我使用 Apple 的 PageControl 示例代码中的代码来构建包含许多 View Controller 的 ScrollView 。

- (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];
    }

}

问题是当我在表格 View 和 ScrollView (根据 Instruments)之间切换时,事件 View Controller (此处为 MainViewController)的数量不断增加,即使我没有添加任何会导致内存问题的新对象。

我在 ScrollView 的 viewWillDisappear 中尝试了很多东西,例如:
- (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

这是 ScrollView 的 viewWillAppear 方法:
- (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

以及显示负责调用者的屏幕截图:
enter image description here

谢谢你。

最佳答案

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

示例项目设计用于固定数量的页面 (kNumberOfPages)。 ScrollView 内容大小和 View Controller 数组的大小取决于页数。示例代码在仅调用一次的 awakeFromNib 中进行了设置。

因此,为了使这种动态化,您可以在页面数量发生变化时重新创建整个 ContentController。您只需要为页数添加一个属性。

另一种选择是在页数更改时重置 ScrollView 和 View Controller 数组。

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

@property(nonatomic,retain) NSArray* eventsArray;

然后你可以像这样添加一个 setter 方法:
-(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];
    }
}

当用户切换到 ScrollView 时,您从 TableView Controller 调用此方法。

关于ios - 在 ScrollView 中释放多个 View Controller 的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13118926/

相关文章:

linux - 是否可以延迟 Linux OOM Killer 并运行我的进程?

ios - 文件名匹配 initWithNibName 的规则是什么?

ios - AFJSONRequestOperation 不更新 block 外的内容

ios - 使用 Cocoapods 响应 native

c - memwatch的内存损坏和崩溃问题

android - Recycler View 中的 OutOfMemory 错误

ios - UIViewController 中的 UITableView

iphone - 难以理解通用应用程序、多个 View Controller 和 xib 文件

ios - 在 iOS 应用程序中登录 Facebook

ios - 扩展 UITableviewController 的 xcode 键盘滚动问题