如何释放子视图控制器的内存

Posted

技术标签:

【中文标题】如何释放子视图控制器的内存【英文标题】:How to release memory of child view controllers 【发布时间】:2014-05-05 08:27:31 【问题描述】:

我有一个页面视图控制器,其中有四个视图控制器。我的问题是,当我转到第二个视图控制器时,我需要为其他三个视图控制器释放第一、第三和第四个视图控制器的内存。如何找到无论是使用instruments为视图控制器分配还是取消分配内存。我尝试使用dealloc,但该方法没有被调用,我正在使用arc。我的代码如下

-(NewsViewController *)news



if (!news) 

UIStoryboard *storyboard = self.storyboard;
news = [storyboard instantiateViewControllerWithIdentifier:@"News"];


return news;



-(PriceViewController *)price 


  if (!price) 

    UIStoryboard *storyboard = self.storyboard;
    price = [storyboard instantiateViewControllerWithIdentifier:@"price"];

  
return price;



- (CommentryViewController *)commentry 

if (!commentry) 
    UIStoryboard *storyboard = self.storyboard;
    commentry = [storyboard instantiateViewControllerWithIdentifier:@"commentry"];


return commentry;


-(WatchlistViewController *)watchlist 

if (!watchlist) 
    UIStoryboard *storyboard = self.storyboard;
    watchlist = [storyboard instantiateViewControllerWithIdentifier:@"watchlist"];


return watchlist;



- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController 

UIViewController *nextViewController = nil;

if (viewController == self.news) 
    nextViewController = self.commentry;



else if(viewController == self.commentry) 
            titleView.text = @"Commentry";
    [titleView sizeToFit];

    //self.title=@"Commentry";
    nextViewController = self.price;


else if(viewController == self.price) 

    titleView.text = @"Price";
    [titleView sizeToFit];
    nextViewController = self.watchlist;



else if(viewController == self.watchlist) 
    titleView.text = @"WatchList";
    [titleView sizeToFit];



return nextViewController;


- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController 

UIViewController *prevViewController = nil;

if (viewController==self.watchlist) 
    titleView.text = @"WatchList";
    prevViewController = self.price;



else if (viewController == self.price) 
        titleView.text = @"Price";
    prevViewController = self.commentry;
       
else if (viewController == self.commentry) 
    titleView.text = @"Commentry";
    prevViewController = self.news;



else if(viewController == self.news) 

    titleView.text = @"News";


return prevViewController;

【问题讨论】:

你启用了 ARC 吗? @Mepla:你读过这个问题吗?他启用了 ARC。 ON-T:网上有关于如何使用 Instruments 的很好的指南。谷歌,你会发现。我敢打赌,你有一些变量保留“自我”,因此你的 dealloc 永远不会被调用。这也取决于您使用的导航控制器,因为其中一些仅在您从 VC 队列中弹出时调用“dealloc”。 我已经发布了我的页面控制器的一些代码。我已经阅读了这些教程,但无法弄清楚。 【参考方案1】:

UIPageViewController 中,如果您调用-viewControllers,您应该会看到所有视图控制器都加载到内存中,如果这个数组中充满了一些,您不应该强制释放它们,因为页面视图控制器可以很好地管理内存很好地从该数组中删除不需要的视图控制器。这意味着如果没有其他人拥有它们的所有权,则将被解除分配,您应该会看到内存分配工具有所减少。 视图控制器有自己的方式来处理他们的内存占用(规则总是与语言相同,但是有一个内部机制可以帮助保持低内存),这是因为视图控制器本身不会占用太多内存,但它们加载的资源会。 自 ios 6 以来,VC 中的内存管理行为发生了很大变化(我将仅讨论这一点),当系统需要内存时,不可见的 VC 将其视图支持层标记为已准备好释放的脏视图,通常这释放了很多内存,但是如果在视图控制器中创建并获取很多对象的所有权,则永远无法释放此内存,除非您在方法 -didReceiveMemoryWarning 中这样做,或者您在你已经用完了它们。 你永远不应该调用 dealloc 并且在 ARC 中也是被禁止的,如果你有一个巨大的内存增长内存,你需要检查你如何管理这些对象的内存。 我举一个例子要清楚,假设在您的页面 VC 中,您使用全屏图像加载其他 VC,如果您使用 +imageNamed 加载它们,这些图像将在缓存中完成,即使您的 VC 正确释放图像占用将保留。

【讨论】:

所以我不需要在这个场景中做任何特殊的dealloc。 是真的..? '视图控制器有自己的方式来释放内存' 不完全正确,但我不知道如何解释,如果它们的保留计数变为 0,它们将完全解除分配并释放它们的内存,但它们也自己管理对象的内存。如果您在由导航控制器加载的视图控制器堆栈中,则处于内存压力情况下的导航控制器将通过向不可见的视图控制器传递内存警告来要求它们释放一些内存。得到它?规则当然与语言相同,但在 VC 中还有一种内部机制有助于保持低内存水平。 @yashwanth777 如果你做得很好,你不需要照顾它,除了你自己加载的资源。规则总是一样的:懒惰地实例化资源,并在您不再需要它们时立即删除它们,不再引用它们(ARC 会处理它们)。 当我看到使用堆快照的内存分配时,我发现当我转到相应的控制器时它会增加,当我回来时它会减少。当它不断维护时它变为 0。这表明它工作正常。

以上是关于如何释放子视图控制器的内存的主要内容,如果未能解决你的问题,请参考以下文章

ARC 和dismissModalViewControllerAnimated:视图控制器内存未释放

弹出视图控制器调用是不是释放其所有属性?

UIViewController 在 dealloc 时不释放子视图(使用 ARC)

目标c-关闭集合视图控制器后未释放常驻内存和脏内存

使用导航控制器弹出视图控制器时释放内存的问题

添加没有navigationController的子视图时正确释放ViewController