3

我有这个与苹果示例相同的页面控制代码。这里我有一个包含 ImageView 的子视图(controller.view)。现在的问题是内存管理。一切正常。但是当我滚动 5-10 页时。RAM 被填满。我试图释放视图+控制器,但没有找到任何合适的位置/方式。我想释放当前不可见的视图。(当前、上一个和下一个视图除外)

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    NSMutableArray *controllers = [[NSMutableArray alloc] init];
    for (unsigned i = 0; i < kNumberOfPages; i++) {
        [controllers addObject:[NSNull null]];
    }
    self.viewControllers = controllers;
    [controllers release];

    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 = 0;

    [self loadScrollViewWithPage:0];
    [self loadScrollViewWithPage:1];
}
- (void)loadScrollViewWithPage:(int)page {
    if (page < 0) return;
    if (page >= kNumberOfPages) return;

    PageControlExampleViewControl *controller = [viewControllers objectAtIndex:page];
    if ((NSNull *)controller == [NSNull null]) {
        controller = [[PageControlExampleViewControl alloc] initWithPageNumber:page];
        [viewControllers replaceObjectAtIndex:page withObject:controller];
        [controller release];
    }

    if (nil == controller.view.superview) {
        CGRect frame = scrollView.frame;
        frame.origin.x = frame.size.width * page;
        frame.origin.y = 0;
        controller.view.frame = frame;
        [scrollView addSubview:controller.view];
    }
}

- (void)scrollViewDidScroll:(UIScrollView *)sender {
  if (pageControlUsed) {
        return;
    }
    CGFloat pageWidth = scrollView.frame.size.width;
    int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
    pageControl.currentPage = page;

    [self loadScrollViewWithPage:page - 1];
    [self loadScrollViewWithPage:page];
    [self loadScrollViewWithPage:page + 1];

}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    pageControlUsed = NO;
}
- (IBAction)changePage:(id)sender {
    int page = pageControl.currentPage;
    [self loadScrollViewWithPage:page - 1];
    [self loadScrollViewWithPage:page];
    [self loadScrollViewWithPage:page + 1];
    CGRect frame = scrollView.frame;
    frame.origin.x = frame.size.width * page;
    frame.origin.y = 0;
    [scrollView scrollRectToVisible:frame animated:YES];
    pageControlUsed = YES;
}
4

4 回答 4

4

我尝试了几个小时 Deepmist 的代码。它完成了这项工作,但我收到了内存警告,并且我的应用程序每滚动 25-30 页就会崩溃(我在页面中使用大图像)。在 Instruments 中,我注意到内存使用量很大:即使从 superview 中一次又一次地删除了不必要的视图并将相关的 viewControllers 替换为 NSNulls,Instruments 显示,每个 4-5MB 的页面滚动都会增加实际内存!

在网上搜索我发现这是一个常见的问题。如果你也有这个问题,你应该尝试以下检查:

1) 在每个视图中,一定要使用 imageWithContentsOfFile 而不是 imageNamed。如记录的 imageNamed 缓存图像并增加内存大小。

2) 在 Deepmist 代码中,之后:

[controller.view removeFromSuperview];

您还必须将视图设置为零:

controller.view=nil;

这个技巧解决了内存消耗,现在对于仅加载的三个视图(当前、current-1 和 current+1 以避免在页面滚动中闪烁)是稳定的。

希望这可以帮助!

于 2011-06-11T17:53:05.570 回答
1

我没有对此进行测试,但我想您可以编写一个与加载相反的方法,如下所示:

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

    PageControlExampleViewControl *controller = [viewControllers objectAtIndex:page];

    if ((NSNull *)controller != [NSNull null]) {
        if (nil != controller.view.superview)
            [controller.view removeFromSuperview];

        [viewControllers replaceObjectAtIndex:page withObject:[NSNull null]];            
    }
}

然后将一些代码添加到您的 didScroll 方法中,如下所示:

[self unloadScrollViewWithPage:page - 2];
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
[self unloadScrollViewWithPage:page + 2];
于 2011-03-28T21:59:46.763 回答
0

试试这个VSScrollview ,它重用它的视图,就像 UITableview 重用它的单元格一样。

于 2013-06-24T10:51:04.290 回答
0

在 loadScrollViewWithPage 方法中,就在 if (nil == controller.view.superview) 之前,循环遍历所有视图并将它们全部删除,除了当前 -1、当前和当前 + 1,但前提是使用当前索引视图调用方法。另外,不要忘记用 NSNulls 替换 viewControllers 数组中的那些视图控制器。

于 2011-03-28T21:43:50.807 回答