在viewDidUnload中将nil设置为子视图控制器

时间:2012-06-02 17:57:53

标签: ios memory-management viewdidunload childviewcontroller

我的iOS应用是基于导航的,具有以下结构:

@interface ViewControllerA : UIViewController
@property (strong,nonatomic) ViewControllerB *viewControllerB;
@property (strong,nonatomic) ViewControllerC *viewControllerC;
...

viewControllerBviewControllerCViewControllerA的{​​{1}}推送之前实例化。

根据我的理解,navigationController中保留的所有内容都应设置为ViewControllerA ViewControllerA中的nil。 我应该对子视图控制器做同样的事情吗?像这样:

viewDidUnload

-(void)viewDidUnload { self.viewControllerB=nil; self.viewControllerC=nil; } 启动了“收到内存警告”时,我发现了一个问题。 之后,调用父视图控制器的viewControllerC(即viewDidUnload),从而将nil设置为'viewControllerB'。出乎意料的是,viewControllerB的viewDidUnload也被调用了。如果我将{0}设置为viewControllerA的{​​{1}}的{​​{1}}个子视图,我就会将“消息发送到已解除分配的对象”。

这是否意味着我不应该将nil设置为子视图控制器? 在这种情况下,内存管理的最佳实践是什么?

P.S。我使用ARC。

1 个答案:

答案 0 :(得分:1)

调用viewDidUnload后,UIViewController应保持其状态,即不释放任何无法轻易重新创建的内容。 通常,您设置为nil与视图层次结构相关的任何数据,例如对viewDidLoad中创建的某些子视图或自定义数据的强引用。在您的示例中,您的父控制器A应该能够在调用viewDidUnload后恢复,这意味着将来调用viewDidLoad将恢复您的控制器而不会崩溃。

此外,所有视图控制器都注册了内存警告通知,因此当发生内存警告时,它们可以卸载当前未显示的任何视图。我不知道视图控制器被调用的顺序是否是确定性的,例如从顶视图控制器调用,因此在父控制器{{1}中将嵌套UIViewController设置为nil时应该谨慎}。

但是,由于您必须在viewDidUnload之后维护您的控制器的状态,因此您不能将您的子控制器设置为nil。您必须做的是放弃控制器子视图上的每个强引用(例如对UILabel的强引用等),但不放弃控制器本身。