我的iOS应用是基于导航的,具有以下结构:
@interface ViewControllerA : UIViewController
@property (strong,nonatomic) ViewControllerB *viewControllerB;
@property (strong,nonatomic) ViewControllerC *viewControllerC;
...
viewControllerB
和viewControllerC
在ViewControllerA
的{{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。
答案 0 :(得分:1)
调用viewDidUnload
后,UIViewController
应保持其状态,即不释放任何无法轻易重新创建的内容。
通常,您设置为nil与视图层次结构相关的任何数据,例如对viewDidLoad
中创建的某些子视图或自定义数据的强引用。在您的示例中,您的父控制器A应该能够在调用viewDidUnload
后恢复,这意味着将来调用viewDidLoad
将恢复您的控制器而不会崩溃。
此外,所有视图控制器都注册了内存警告通知,因此当发生内存警告时,它们可以卸载当前未显示的任何视图。我不知道视图控制器被调用的顺序是否是确定性的,例如从顶视图控制器调用,因此在父控制器{{1}中将嵌套UIViewController
设置为nil时应该谨慎}。
但是,由于您必须在viewDidUnload
之后维护您的控制器的状态,因此您不能将您的子控制器设置为nil。您必须做的是放弃控制器子视图上的每个强引用(例如对UILabel的强引用等),但不放弃控制器本身。