iPhone发展的模拟存储器的警告
题
背景:
我有一个选项栏的应用程序。每个选项包含导航控制器,允许用户的过渡,从一个看到的其他表示深信息的数据(每一个观点是正在处理的图控制器,每个图控制器类 didReceiveMemoryWarning
法)。列出了填充,由拉的数据网络服务。
的问题:
当我使用的"硬件>模拟存储警告"选择的模拟器, didReceiveMemoryWarning
方法被称为对于我所有的图控制器,即使一个用户观看。我不想明确的任何内容正在使用的活性视图控制器。我如何可以实现吗?
这方法应该具有实施重新加载数据的数据后被释放,因为记忆的警告?(我看到的景控制的课程包含一个表中查看电话 viewDidLoad
方法时的用户回来,查看,但如果认为包含(说UIWebView)然后 viewDidLoad
方法不叫。为什么是什么?)
编辑(星期五30January2009-03:10)
(注:我使用的接口建筑商创造景 loadView
方法的评论。)
因此,当一个图控制器的收存预警消息,这些步骤进行:
下述方法被称为:
- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; }
作为结果的呼吁
[super didReceiveMemoryWarning]
,[self setView:nil]
就会自动打的电话?如果任何资源应该被清除,然后
setView
方法应复盖到明确的当地资源。[self setView:nil]
不是如果认为当前活动(通过默认)。对吗?-我真的好奇,这种方法需要这种决定,以及如何?
可以请你确认。另外,我得到一个错误,按照这一办法,但增加 myObject = nil
释放后 myObject
在 dealloc
方法的控制器类固定的问题。谢谢。
解决方案
这是一个老问题,但是我没有看到一个适当的答复,所以在这里:
当一个存储器的警告是收到, -didReceiveMemoryWarning
被称为所有图控制器,无论他们是"当前"一个或没有。图控制器是简单地倾听的记忆警告事件的广播。
如果图控制的查看是不是正在使用当时存储器报警,控制器将卸它通过设置的财产,以为零。它怎么知道如果认为使用?通过查看的 -superview
财产。如果 view.superview
是零,查看是不是部分的任何树和可以被卸载的安全。
一旦发生这种情况,控制器 -viewDidUnload
被称为。这是正确的地点卸下的任何网,以及任何会得到重新建立在 -viewDidLoad
.
是什么 -didReceiveMemoryWarning
用的?你的控制器可能有的对象没有得到实例,直到访问。例如,你可以有一个控制器,有时需要一个大块的数据从一个文件,但不总是如此。你可以有一个位置对于它是这样的:
- (NSData*)bigChunkOfData {
// Get data from our instance variable _data, read from disk if necessary
if (_data == nil) {
_data = [[NSData alloc] initWithContentsOfFile:@"/path/to/data"];
}
return _data;
}
这将读取数据从磁盘该第一时间,然后把它放在一个实例可变的。由于 _data
变量是创建上的需求,这是安全的我们卸它在低存情况:它只会创建的下次我们需要它。
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
[_data release];
_data = nil; // <-- Very important: don't leave strong references dangling.
}
其他提示
我做的,我清理这样的:
-(void)setView:(UIView*)view
{
[super setView:view];
if(view == nil)
{
// Our view has been cleared, therefore we should clean up everything
// we are not currently using
....
setView:nil
由UIViewController在回应一个存储警告,如果这种看法目前不可见-这基本上是什么你想知道的。
编辑
在回答后续行动:
- 正确的。
- 这就是我做的,它为我工作。
正确的。执行情况
didReceiveMemoryWarning
在UIViewController是什么这样做。如果你不复盖didReceiveMemoryWarning
, 然后基类实现在UIViewController将被称为-如果你复盖,很明显你应该叫:[super didReceiveMemoryWarning]
确保我没有处理这种为每一个viewcontroller我写的..我只是做了一个模式ViewController模板,其中提供了准则,其目的释放和当..
更多的解释这里 http://iphone2020.wordpress.com/2010/05/30/efficient-memory-handling-in-uiviewcontroller-part-1/
希望找到有用的。
在关于看管和存储警告:
UIKit不仅允许的导航回从图控制器,但也可以使导航向其他图控制从现有的。在这样的情况下,一个新的UIViewController将分配,然后装入图。老图控制器将去掉屏幕和变得不活跃,但是仍拥有许多的对象–中的一些自定属性和变量和其他人在看酒店/层次结构。所以没有的新的可见图控制器、在考虑到其观点的对象。
由于有限数量的存储器的移动设备,拥有的两套目的–一个在离屏幕上的图控制器,另一个在屏幕上的图控制器可能太多,以处理。如果UIKit认为有必要,它可以收回的一些关屏幕上的图控制器的存储器,这是未表示反正;UIKit知道这看控制器在屏幕上这是幕,因为毕竟,这是一个管理(当你打电话 presentModalViewController:animated:
或 dismissModalViewControllerAnimated:
).所以,每次感觉压力,UIKit产生记忆的警告,这卸载并释放你的屏幕景观层次,然后打电话给你定制viewDidUnload方法对你做同样的,为你的属性和变量。UIKit版本的自我。图自动地,使我们然后手动释放我们的变量和性质在我们viewDidUnload代码。它这样做的所有屏幕图控制器。
当该系统运行的存储器,火 didReceiveMemoryWarning
.屏幕观点将在回收和释放后的存储器的警告,但是你的屏幕上的图不会得到释放–这是可见和需要。在情况类拥有大量的存储器,诸如高速缓存、图像等, didReceiveMemoryWarning
是你应该清洗它们,即使他们是在屏幕;否则,您的程序可能是终止glutting系统的资源。你需要替代这种方法来确保清洁了你的记忆;只要记住你打电话 [super didReceiveMemoryWarning];
.
一个甚至更详细的解释是: http://myok12.wordpress.com/2010/11/30/custom-uiviewcontrollers-their-views-and-their-memory-management/
幸运的是,模拟器中有一个便利功能,允许你把低存储情况的测试。把一些只()发言两viewDidLoad和didReceiveMemoryWarning,像这样:康
- (void)viewDidLoad {
NSLog(@"viewDidLoad");
...
}
- (void)didReceiveMemoryWarning {
NSLog(@"didReceiveMemoryWarning");
}