我已经开发了一个简单的位置感知的iPhone应用程序,它在功能上非常好地工作,除了在手机的低内存条件下。
在手机内存不足的情况下,我的应用程序就会崩溃,如果我通过腾出一些空间来增加手机内存,它就会在没有崩溃的情况下再次正常工作。
当我搜索这个问题时,我发现在低内存条件下,操作系统将向当前层次结构中的所有控制器发送didReceiveMemoryWarning,这样每个控制器都应该实现didReceiveMemoryWarning方法,并将当前不可见的视图设置为零。
我还在某个地方读到,如果该控制器的视图不可见,则将调用带有nil参数的方法setView,并且如果与视图附加了一些出口变量,则删除它们会出现问题。
因此,有了这些基金,通过实现didReceiveMemoryWarning和viewDidUnload方法,处理Iphone引发的低级别内存状况的最佳方法是什么。
请给出一个适当的例子或链接,如果可能的话,解决上述问题。
谢谢。
发布于 2010-03-24 06:11:18
举个例子,我是posting...which,我抄袭了一些地方.可能会给你一些想法..。
- (void)didReceiveMemoryWarning {
// Release anything that's not essential, such as cached data (meaning
// instance variables, and what else...?)
// Obviously can't access local variables such as defined in method
// loadView, so can't release them here We can set some instance variables
// as nil, rather than call the release method on them, if we have defined
// setters that retain nil and release their old values (such as through use
// of @synthesize). This can be a better approach than using the release
// method, because this prevents a variable from pointing to random remnant
// data. Note in contrast, that setting a variable directly (using "=" and
// not using the setter), would result in a memory leak.
self.myStringB = nil;
self.myStringD = nil;
[myStringA release];// No setter defined - must release it this way
[myStringC release];// No setter defined - must release it this way
/* 3. MUST CONFIRM: NOT necessary to release outlets here - See override of
setView instead.
self.labelA = nil;
self.imageViewA = nil;
self.subViewA = nil;
*/
// Releases the view if it doesn't have a superview
[super didReceiveMemoryWarning];
}发布于 2010-03-31 00:32:29
内存警告是向您发出的一个信号,即您应该处理任何并非绝对重要的资源。大多数控制器将保存数据缓存、中间数据或其他部分,通常是为了保存重新计算。当他们收到内存警告时,他们应该开始冲洗任何他们不需要立即操作的东西。
如何确定什么是“关键”完全取决于应用程序的设计。例如,一个OpenGL游戏可以确定当前屏幕上的纹理是有价值的,并且是不可见的刷新纹理,或者是当前游戏区域之外的级别数据。具有大量会话日志(如IRC客户端)的应用程序可以将它们从内存中释放出来并放到磁盘上。
正如您所观察到的,警告被发送到您层次结构中的每个控制器,因此每一段都需要单独确定哪些数据构成“操作的关键”以及什么构成“消耗性”。如果您已经对它们进行了优化,并且仍然在摆脱内存警告,那么不幸的是,是时候重新检查您的核心应用程序设计了,因为您已经超出了硬件的限制。
发布于 2013-04-08 09:03:49
在iOS 5和更高版本上。
当控制器收到内存警告时,将调用didReceiveMemoryWarning。此时,如果控制器的视图不在视图层次结构中,则视图将被设置为零,而viewDidUnload将自动调用。所以,我们在viewDidUnload中必须做的事情是发布在viewDidLoad中创建的子视图或从Nib中创建的子视图。如下所示:
- (void)viewDidUnload
{
self.subView = nil;
self.subViewFromNib = nil;
}
- (void)didReceiveMemoryWarning
{
self.someDataCanBeRecreatedEasily = nil;
[super didReceiveMemoryWarning];
}在iOS6上。
当收到内存警告时,控制器不会自动释放视图。因此,viewDidUnload永远不会被调用。但是当memry警告发生时,我们仍然需要发布我们的视图(包括子视图)。就像这样。
- (void)didReceiveMemoryWarning
{
if ([self isViewLoaded] && [self.view window] == nil) {
self.view = nil;
self.subView = nil;
self.subViewFromNib = nil;
}
self.someDataCanBeRecreatedEasily = nil;
[super didReceiveMemoryWarning];
}注意,在我们知道视图已经加载之前,我们不会调用self视图。因为如果未加载视图,此方法将自动加载视图。
注意,我们可以在视图未添加到窗口时发布该视图。
https://stackoverflow.com/questions/2430728
复制相似问题