我有一个相对简单的问题,一段时间以来一直在逃避解决方案。我有一个视图控制器和一个关联的XIB。视图控制器称为FooterViewController
。 FooterViewController
的视图被设置为tableview的页脚视图。
FooterViewController
的视图包含一个标签,用于向用户显示反馈。我想这个标签一直存在,直到我的应用程序改变它的值。在正常情况下,确实如此。但是,我刚刚开始测试内存警告,并且我发现在响应内存警告而卸载视图后,标签被清除。
以下是我迄今为止尝试解决问题的方法:在FooterViewController
的{{1}}方法中,我将标签的文本存储在名为viewWillUnload
的实例变量中:
statusString
请注意,我还将另一个声明为- (void)viewWillUnload
{
statusString = [statusLabel text];
testInt = 5;
NSLog(@"View will unload; status string = %@; testInt = %d",
statusString, testInt);
[super viewWillUnload];
}
的实例变量设置为5.
然后,在NSInteger testInt
的{{1}}方法中,我尝试将标签的文字设置为FooterViewController
:
viewDidLoad
然而,这不起作用。此外,在模拟内存警告后的日志中,我看到:
statusString
(注意“无效的IP地址错误代码:113”是statusString的正确值)
然后,在再次导航到- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"Just before setting label, statusString: %@; testInt: %d",
statusString, testInt);
[statusLabel setText:statusString];
NSLog(@"View did load.");
}
之后,我看到了:
View will unload; status string = Invalid IP address Error code: 113; testInt = 5
这向我表明,由于某种原因,当视图再次加载时,FooterViewController
的实例变量正在重新初始化。最后一点:每次视图必须重新加载时,都会调用方法Just before setting label, statusString: (null); testInt: 0
,尽管我希望如此;毕竟,必须从NIB重新加载视图。
所以,我的问题是:
谢谢, 莱利
答案 0 :(得分:0)
statusString看起来像弱引用,而不是强属性。它不能保留标签的文本,当卸载视图时,该文本会被标签取消分配。这就是为什么你得到第一个正确的值(在标签被释放之前),以及之后为null(在标签被释放之后,弱ref无效)的原因。将你的statusString变成一个强大的属性,ARC魔法不会再咬你了。
答案 1 :(得分:0)
看起来你需要使用didRecieveMemoryWarning而不是viewDidUnload,因为在发生内存警告时不能保证调用viewDidUnload。如果崩溃完全退出应用程序,那么您需要使用coreData之类的东西将数据写入磁盘。将数据保存在此处,然后调用super,以便仍然可以发布视图。希望有所帮助。
答案 2 :(得分:0)
我终于明白了发生了什么事。问题是我在其父视图控制器的FooterViewController
方法中调用了viewDidLoad
的分配和初始化方法。当视图被转储并随后重新加载时,我的视图控制器被重新初始化!这破坏了原始的FooterViewController
,它保留了我需要的实例变量,并用一个全新的VC替换它。
解决方案是将[[FooterViewController alloc] init]
移动到init
的父VC的FooterViewController
方法,以便每个运行周期仅执行一次初始化。
我已经吸取了教训:不要重新初始化视图控制器,除非你真的想这样做。因此,在父视图控制器中调用初始化程序时要非常小心
感谢我从两位回答者那里得到的帮助。