防止在内存警告时清除实例变量

时间:2012-06-18 17:42:21

标签: objective-c ios memory-warning

我有一个相对简单的问题,一段时间以来一直在逃避解决方案。我有一个视图控制器和一个关联的XIB。视图控制器称为FooterViewControllerFooterViewController的视图被设置为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重新加载视图。

所以,我的问题是:

  1. 为什么这些实例变量在卸载和重新加载视图的过程中似乎无效或归零?
  2. 如果我做错了导致这种无效的事情,那是什么?
  3. 如果我没有做错任何事情,这是正常行为,我应该如何处理维护视图负载之间的状态?
  4. 谢谢, 莱利

3 个答案:

答案 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方法,以便每个运行周期仅执行一次初始化。

我已经吸取了教训:不要重新初始化视图控制器,除非你真的想这样做。因此,在父视图控制器中调用初始化程序时要非常小心

感谢我从两位回答者那里得到的帮助。