首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ViewWillDisappear与dealloc

ViewWillDisappear与dealloc
EN

Stack Overflow用户
提问于 2010-09-25 00:00:11
回答 2查看 4.8K关注 0票数 4

我在视图控制器的dealloc方法中放入了一个NSlog。它不会得到一致的调用。我确实注意到ViewWillDisappear确实总是被调用。把我所有整洁的升级代码都移到这里可以吗?将内容设置为Nil并释放调用。

有人对为什么dealloc没有被调用有什么建议吗?我知道在文档中它可能不会被调用,但如果你有一个非常简单的应用程序,它总是被调用。所以我做的某些事肯定影响了去配给。

这是调用我的ViewController的代码,而不是总是调用我的dealloc。

代码语言:javascript
复制
-(IBAction) playComputerTapped:(id)sender
{

PlayGameViewController *pgvc = [PlayGameViewController alloc:@“PlayGameViewController”捆绑包:NSBundle mainBundle];pgvc.gameMode = 1;自呈现presentModalViewController:pgvc动画:是;pgvc发布;}

上面的代码将我从邮件菜单ViewController带到游戏中。

下面是离开gameViewController并返回菜单的代码。

代码语言:javascript
复制
[self.parentViewController dismissModalViewControllerAnimated:YES];

谢谢-Code

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-09-25 01:31:26

你不是说用viewWillDisappear代替viewDidUnload吗?

当视图控制器消失时,调用viewWillDisappear。当视图控制器被弹出,或者其他视图控制器被推入堆栈时,通常会发生这种情况。viewWillDisappear的目的是停止活动的动作-例如停止动画,隐藏一些元素或类似的。

viewDidUnload可能就是你想要的,因为这个是在视图控制器的视图被卸载时调用的。对于当前可见的视图控制器,这应该永远不会发生,只会发生在导航堆栈中的某个位置( UITabBarController或UINavigationController的一部分),但当前不可见的控制器。viewDidUnload的目的是释放视图中的任何UI元素,同时保留视图控制器。

要理解这一点,重要的是要了解为什么要卸载此类控制器的视图。原因是内存消耗。视图即使在当前不可见的情况下也会消耗大量的内存。视图通常很容易重建-只需调用最初构造视图的代码即可。如果您使用的是Interface Builder,这尤其容易。因此,这些视图是释放以获得更多内存的最佳候选者。

当系统没有足够的内存时,它开始调用当前不可见的视图控制器的didReceiveMemoryWarning方法。如果你已经在Xcode中从模板创建了你的控制器,这个方法简单的调用超级的(UIViewController)实现[super didReceiveMemoryWarning]。该默认实现将释放self.view,这反过来应该释放它以及它的所有子视图。

现在假设您的视图控制器需要访问一些子视图,以便以某种方式对其进行操作。例如,您可以在那里有一个UILabel元素,并希望相应地更改其内容。要访问该元素,需要创建一个成员变量(IBOutlet)并将其连接到该元素。现在你的视图控制器拥有这个标签,所以它的保留计数增加了。当控制器的视图被释放时,标签也会被释放,但是因为视图控制器仍然保留着标签,所以它不会被释放。因此,您应该在viewDidUnload方法中释放标签。

我见过以编程方式(在loadView方法中)创建视图的应用程序,但是加载的方式太脏了,以至于一旦释放视图就不可能重新构造它。因此,每次系统内存不足时,它都会调用didReceiveMemoryWarning,然后释放视图,但在导航回该视图控制器后,应用程序就会崩溃。一个快速的“错误修复”是删除视图控制器中的[super didReceiveMemoryWarning]调用。嗯,系统没有获得内存,出现了一些奇怪的效果,但至少应用程序没有立即崩溃。

现在是第三个-- dealloc。当对象不归任何人所有,并且它的内存将被释放时,就会调用这个函数。在这里,您需要释放您保留的所有对象。对于视图控制器,这些通常是对模型类的引用。

我想再描述一个可能的场景。假设您有一个视图控制器来显示与另一个人的聊天。假设这是一个非常花哨的聊天,带有表情图标和好友图标。假设每个聊天条目都显示为UITableView的一个单元格。

当您的好友向您发送消息时,您希望通过重新加载将新单元格追加到表视图中。因此,你的视图控制器有一个通向表视图的出口。

viewWillDisappear中,你应该停止表情和图标的动画。在viewDidUnload中,您应该释放表视图。在dealloc中,您希望发布聊天的历史记录(可能是在此对话期间发送和接收的所有消息的NSArray )。

现在,如果你离开你的聊天,viewWillDisappear会被调用,你会停止动画。

当系统内存不足,并且您的视图控制器不可见时,将调用didReceiveMemoryWarning并释放视图。你的viewDidUnload会被调用,你会释放UITableView,这样它就可以真正被释放了。

当您导航回聊天时,将再次调用loadView,并再次构造视图,之后将调用viewDidLoad。您的模型(聊天对话的表示)仍然在那里,因此表视图的数据源具有与以前一样的所有数据,因此表视图将显示与视图释放之前完全相同的内容。毕竟,viewWill/DidAppear是在动画开始的地方调用的。

当你和你的朋友聊天结束后,你释放视图控制器,它被释放- dealloc被调用,你释放一个包含聊天消息的数组,并清理其他所有东西。

我希望它能让事情变得更清晰。

票数 11
EN

Stack Overflow用户

发布于 2010-09-25 00:15:59

那得看情况了。

如果你需要减少你的应用程序的内存占用,在视图不可见时通过viewWillDisappear卸载是一个很好的方法。然而,一旦视图再次显示,您将需要重新初始化所有内容,这取决于它的内容,这可能会产生相当大的开销-甚至可能不需要。

对于一个小的应用程序(就内存使用而言),使用dealloc卸载你的东西是很好的。只有当对象保留计数降为零并且是在对象被销毁之前运行的最后一个方法时,才会调用它。使用自动释放时,情况可能不是这样,当然,对象可以由parentviewcontroller以外的其他对象保留,从而防止它被销毁并因此dealloc被调用。

你可能想看看Memory Management Programming Guide,它会解释更多的细节。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3788864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档