首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何实现didReceiveMemoryWarning?

如何实现didReceiveMemoryWarning?
EN

Stack Overflow用户
提问于 2010-03-12 05:41:27
回答 6查看 48.8K关注 0票数 56

我已经开发了一个简单的位置感知的iPhone应用程序,它在功能上非常好地工作,除了在手机的低内存条件下。

在手机内存不足的情况下,我的应用程序就会崩溃,如果我通过腾出一些空间来增加手机内存,它就会在没有崩溃的情况下再次正常工作。

当我搜索这个问题时,我发现在低内存条件下,操作系统将向当前层次结构中的所有控制器发送didReceiveMemoryWarning,这样每个控制器都应该实现didReceiveMemoryWarning方法,并将当前不可见的视图设置为零。

我还在某个地方读到,如果该控制器的视图不可见,则将调用带有nil参数的方法setView,并且如果与视图附加了一些出口变量,则删除它们会出现问题。

因此,有了这些基金,通过实现didReceiveMemoryWarningviewDidUnload方法,处理Iphone引发的低级别内存状况的最佳方法是什么。

请给出一个适当的例子或链接,如果可能的话,解决上述问题。

谢谢。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-03-24 06:11:18

举个例子,我是posting...which,我抄袭了一些地方.可能会给你一些想法..。

代码语言:javascript
复制
- (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];
}
票数 24
EN

Stack Overflow用户

发布于 2010-03-31 00:32:29

内存警告是向您发出的一个信号,即您应该处理任何并非绝对重要的资源。大多数控制器将保存数据缓存、中间数据或其他部分,通常是为了保存重新计算。当他们收到内存警告时,他们应该开始冲洗任何他们不需要立即操作的东西。

如何确定什么是“关键”完全取决于应用程序的设计。例如,一个OpenGL游戏可以确定当前屏幕上的纹理是有价值的,并且是不可见的刷新纹理,或者是当前游戏区域之外的级别数据。具有大量会话日志(如IRC客户端)的应用程序可以将它们从内存中释放出来并放到磁盘上。

正如您所观察到的,警告被发送到您层次结构中的每个控制器,因此每一段都需要单独确定哪些数据构成“操作的关键”以及什么构成“消耗性”。如果您已经对它们进行了优化,并且仍然在摆脱内存警告,那么不幸的是,是时候重新检查您的核心应用程序设计了,因为您已经超出了硬件的限制。

票数 17
EN

Stack Overflow用户

发布于 2013-04-08 09:03:49

在iOS 5和更高版本上。

当控制器收到内存警告时,将调用didReceiveMemoryWarning。此时,如果控制器的视图不在视图层次结构中,则视图将被设置为零,而viewDidUnload将自动调用。所以,我们在viewDidUnload中必须做的事情是发布在viewDidLoad中创建的子视图或从Nib中创建的子视图。如下所示:

代码语言:javascript
复制
- (void)viewDidUnload
{
    self.subView = nil;
    self.subViewFromNib = nil;
}

- (void)didReceiveMemoryWarning
{
    self.someDataCanBeRecreatedEasily = nil;
    [super didReceiveMemoryWarning];
}

在iOS6上。

当收到内存警告时,控制器不会自动释放视图。因此,viewDidUnload永远不会被调用。但是当memry警告发生时,我们仍然需要发布我们的视图(包括子视图)。就像这样。

代码语言:javascript
复制
- (void)didReceiveMemoryWarning
{
    if ([self isViewLoaded] && [self.view window] == nil) {
        self.view = nil;
        self.subView = nil;
        self.subViewFromNib = nil;
    }
    self.someDataCanBeRecreatedEasily = nil;
    [super didReceiveMemoryWarning];
}

注意,在我们知道视图已经加载之前,我们不会调用self视图。因为如果未加载视图,此方法将自动加载视图。

注意,我们可以在视图未添加到窗口时发布该视图。

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2430728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档