iOS内存警告处理

1.    内存警告的说明

在iOS6.0之后,不再支持viewWillUnload 和 viewDidUnload。但依然支持didReceiveMemoryWarning。之所以不支持viewWillUnload和 viewDidUnload,官方文档的解释是:当view不在window视图中时,系统会自动释放view中的耗内存的资源,view中剩余的资源所占内存极小,不值得系统为了节省内存而自动去释放,然后再重新创建视图层次。

The answer I eventually got back from Apple:
Your "large resources" happen to be images that you've loaded cached via +imageNamed:. Because they are loaded cached, they are exempted from the automatic cleanup. Generally only content generated via -drawRect: or by Core Animation is automatically released here. Because your views continue to exist, they continue to hold a reference to these cached images, and we can't purge them on memory warning either

2.    导致的问题

如上导致的问题是:系统会自动控制释放view,但是其retain/strong属性的子view无法得到释放。

3.    官方的解决

- (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Add code to clean up any of your own resources that are no longer necessary.

    if ([self.view window] == nil)

    {

        // Add code to preserve data stored in the views that might be

        // needed later.

 

        // Add code to clean up other strong references to the view in

        // the view hierarchy.

        self.view = nil;

    }

官方代码的理解:

[self.view window] == nil 这段代码和ios5中调用viewWillUnload的判断条件一样:满足self.view存在;self.view可被释放,即不在任何视图层次中。

官方代码的问题:

在 [self.view window]== nil 中,如果当前的view未创建,接受到了内存警告,则该段代码导致系统生成view,然后在self.view= nil又释放掉了。

 

4.   可以采用的实现方式

// will not be called in iOS 6, see iOS docs

- (void)viewWillUnload

{

       [super viewWillUnload];

       [selfmy_viewWillUnload];

}

 

// will not be called in iOS 6, see iOS docs

- (void)viewDidUnload

{

       [super viewDidUnload];

       [selfmy_viewDidUnload];

}

 

// in iOS 6, view is no longer unloaded so do it manually

- (void)didReceiveMemoryWarning

{

       [superdidReceiveMemoryWarning];

       if ([self isViewLoaded]&& [self.viewwindow] ==nil) {

           [selfmy_viewWillUnload];

           self.view = nil;

           [selfmy_viewDidUnload];

       }

}

 

- (void)my_viewWillUnload

{

       // prepare to unload view

}

 

- (void)my_viewDidUnload

{

       // the view is unloaded, clean up as normal

}

 

说明:

l   [self.view window] == nil 的基础上增加了另外一个条件[selfisViewLoaded]。[self isViewLoaded]表示系统调用了loadView,并生成了view。这样就可以避免上面所说到的问题。

l   这里在iOS5上也不会出现重复调用my_viewWillUnload和my_viewDidUnload,在didReceiveMemoryWarning 中,系统首先调用了viewWillUnload和viewDidUnload,这时self.view为空,不满足[self  isViewLoaded]。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值