【问题标题】:How to release a viewController and his view inside of an NSMutableArray viewControllers?如何在 NSMutableArray viewControllers 中释放 viewController 和他的视图?
【发布时间】:2011-07-25 16:08:18
【问题描述】:

我的内存管理有一个大问题。 A 实际上有一本大杂志,它的每一页都用他自己的 PageViewController 渲染。我的代码完全基于 Apple 文档的 PageControl 示例,如果你们曾经看过的话。

因此,在“MainViewController”的 viewDidLoad 中,我创建了一个 NSMutableArray = self.viewControllers 充满了 NSNull 对象。我在第一页和第二页打电话给我的[self loadScrollViewPage:page];。当用户导航到更多页面时,我会(从 scrollViewDidScroll)调用更多负载 [self loadScrollViewPage:nextPage];,因为应用程序将需要它。我还实现了unloadScrollViewPage:page,因为杂志太大了,如果我不这样做,内存就会用完。

所以,这是我的代码:

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

问题是,无论我调用多少次unloadScrollViewPage,当我调用loadScrollViewPage 时,内存仍然会增加大小,而不会随着unloadScrollViewPage 而减少。因此,当用户进入第 10 页(300 页,哈哈?)时,我的应用程序的内存大小为 100Mb,当然,它会崩溃:(

我的问题是:

  • 我是否从 self.viewControllers NSMutableArray 正确释放内存?
  • 当我从 self.viewControllers 中删除ObjectAtIndex:pageNumber 时,我放在它们的超级视图(MainViewController 的视图)上的每个控制器的视图会释放它吗?如果没有,我该怎么做?这是我的问题吗?

提前致谢。

编辑:

看起来 Firoze Lafeer 一开始是正确的,问题是我的 UIImage 内存管理和我的视图保留。我只是设法 removeFromSuperview 每个 UIView。对于图像,看起来像使用 [UIImage imageNamed] 它实现了一个缓存(当 ios 需要时释放它¬¬)。我只是改变了使用[UIImage imageWithData:imageData]; 的方式,它没有实现缓存,我所有的对象现在都很开心。谢谢大家。 :)

【问题讨论】:

    标签: objective-c iphone ipad memory memory-management


    【解决方案1】:

    对,当您将每个视图添加到滚动视图时,滚动视图将保留该视图。因此,您必须在卸载每个页面时删除每个视图。

    顺便说一句,我想您会发现视图控制器本身并不会占用太多内存。观点是更大的问题。

    【讨论】:

    • 好的,所以如果该视图有多个子视图,那么我必须在每个子视图中删除它们?...我实际上从放置它的滚动视图中删除了该视图,但内存并没有减少。有什么想法吗?
    • 删除一个视图也会从视图层次结构中删除它的所有子视图。如果视图仍未被释放,您应该在 Instruments 中检查它们的历史记录。实际上,您可以使用 Instruments 来确认这是您的记忆最初的去向。如果您在视图中加载图像,您确定正确管理这些图像吗?
    • Instruments 的哪个组件可以做到这一点?
    • 您可以使用分配。查看对象列表,过滤“MyBigView”或其他内容,然后单击焦点,您将看到保留/释放历史记录。这是一种方法。或者只看统计数据,您可能会发现问题出在一堆图像而不是视图本身。
    • 问题看起来是我显示的一堆图像。每个视图一个图像。虽然我要再下一页,但内存增加了很多(比如每页 10 Mb。我不知道发生了什么:(
    【解决方案2】:

    您的其余代码看起来应该按照您期望的方式运行,但是这两行可能不正确。

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

    第一行将删除对象并将其上方的所有索引减一,因此您的数组将小一。然后,您在曾经比您删除的对象高一个索引的对象上调用 replaceObject。这两行代码将在每次调用时将数组的大小减小一,直到当您传递数组的实际长度时出现越界异常。您可以删除 removeObject 行,replaceObject 将释放该对象它是自己的,同时让你的数组保持相同的大小。

    这可能不会解决您的问题,因为它会以同样的方式减少保留计数器。也许发布调用这些方法的代码会有所帮助。

    【讨论】:

    • 你是对的。但是是的,实际上这并不能解决我的记忆问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多