文档章节

iPhone相机和内存警告

 子寒在秋
发布于 2014/07/15 20:04
字数 1138
阅读 28
收藏 0

现在我们越来越习惯于在程序中使用相机。但是,几乎在程序每次打开相机的瞬间,我们都会收到一个“Received memory warning. Level=1”内存警告 。对于iOS来说,内存永远是稀缺资源 ,因此,在你使用iPhone的高分辨率相机时,尤其需要小心。

程序员应当重视内存警告并对之进行处理,包括:

一、在viewDidUnload方法中释放内存

从iOS3.0开始, 释放内存的代码didReceiveMemoryWarning 迁移到了viewDidUnload中,我们不用覆盖didReceiveMemoryWarning方法。 事实上有不止地方会收到内存警告,因此程序中会有两个地方存在 didReceiveMemoryWarning方法:AppDelegate 和ViewController。一般,我们选择在ViewController而不是AppDelegate中处理内存警告。

当程序收到内存警告时,程序员们就必须注意了。iOS随后会自动清理当前“无用的”内存,比如内存中那些不处于顶层的ViewController和视图。

 

我们一般需要在viewDidUnload方法中,释放视图中无用的对象,比如UILabel、UIButton、NSArray等:

-(void)viewDidUnload

{

     [super viewDidUnload];

   if(ivBg)[ivBg release],ivBg=nil;

    if(btSend)[btSendrelease],btSend=nil;

    if(btUpload)[btUploadrelease],btUpload=nil;

    if(vwBody)[vwBodyrelease],vwBody=nil;

    if(backButton)[backButtonrelease],backButton=nil;

    if(indicator)[indicatorrelease],indicator=nil;

    if(imagePicker)[imagePickerrelease],imagePicker=nil;

    if(receiverVC)[receiverVCrelease],receiverVC=nil;

}

注意,我们释放的对象必须是“无用的”。这些东西可能是任何对象,比如成员对象和UI对象。关键在于怎样认识一个对象是“有用的”还是“无用的”。实际上,对于iOS来说,任何在viewDidUnload方法中释放的东西都是“无用的”。如果你有任何对象在恢复视图时会用到,那么就不要在viewDidUnload方法中释放。例如,用户在视图中的输入——一封邮件的正文,或者用户正在编辑的图片——这些东西将在当相机使用完毕,iOS准备恢复视图时显示给用户。

如果你确实不得不节省出更多的内存,那么你可以在viewDidUnload中把一些有用的东西也释放掉,前提是,当你收到内存警告时,把这些对象持久化(保存到文件)。

而有的对象,它们本来就在xib文件中存在。在iOS恢复视图时,这些东西会从xib中恢复到内存(initWithNibName->viewDidLoad)。比如按钮、图片、静态标签等UI对象。这些对象我们就可以看作是“无用的”,在viewDidUnload方法中可以毫不客气地把它们统统释放。

二、在 didReceiveMemoryWarning 方法中设置内存警告标志

现在,虽然我们已经在viewDidUnload方法中,而不用在 didReceiveMemoryWarning方法中释放对象,但didReceiveMemoryWarning方法仍然有一个用途,就是设置内存警告变量,以让程序员知道何时收到内存警告。

首先声明一个BOOL成员作为是否收到过内存警告的标志:

BOOLmaybeSetViewNil;

然后在didReceiveMemoryWarning方法中:

maybeSetViewNil=YES;

三、在viewDidUnload方法中,保存视图数据以便恢复

在第一步中,我们提到为了“尽可能地”为iOS腾出内存,我们可以把所有对象释放,但对于“有用的”的对象,我们应该采用必要的保存策略,比如保存到文件缓存中。

仍然在viewDidUnload方法中,加入以下代码:

NSMutableDictionary*d=[[NSMutableDictionary alloc]init];

   

//"in use" objects

    if(tfTitle){

        if(tfTitle.text) [d setObject:tfTitle.text forKey:@"tfTitle.text"];

       self.tfTitle=nil;

    }

    if(lbAttach){

        if(lbAttach.text) [d setObject:lbAttach.text forKey:@"lbAttach.text"];

       self.lbAttach=nil;

    }

    if(imageView){

        if(imageView.image) {

           NSData* data=UIImageJPEGRepresentation(imageView.image,0.7);

           if (data)[d setObject:data forKey:@"imageView.image"];

        }

       self.imageView=nil;

    }

    if(receivers){

        [dsetObject:receivers forKey:@"receivers"];

       [receivers release],receivers=nil;

    }

    if(selectedPeople){

        [dsetObject:selectedPeople forKey:@"selectedPeople"];

       [selectedPeople release],selectedPeople=nil;

    }

[VCCachesaveToCache:d toVC:self];

    [d release];

 

可以看到,我们把所有“有用的”对象放到了Dictionary集合中。CCache是一个自定义类,我用它把Dictionary保存到指定文件。

四、恢复视图状态

接下来我们可以在viewDidLoad方法中恢复视图状态了:

selectedPeople=[[NSMutableArrayalloc]init];

    receivers=[[NSMutableStringalloc]init];

    if (maybeSetViewNil) {

       NSLog(@"maybe set view nil!");

       NSDictionary* d=[VCCache loadCache:self];

        if(d!=nil) {// status restore

           id obj=[d objectForKey:@"tfTitle.text"];

           if(obj!=nil)tfTitle.text=(NSString*)obj;

           

           obj=[d objectForKey:@"lbAttach.text"];

           if(obj!=nil)lbAttach.text=(NSString*)obj;

           

           obj=[d objectForKey:@"imageView.image"];

           if(obj!=nil)imageView.image=[UIImage imageWithData:(NSData*)obj];

           

⋯⋯

           

           obj=[d objectForKey:@"receivers"];

           if(obj!=nil)[receivers setString:(NSString*)obj];

           

           obj=[d objectForKey:@"selectedPeople"];

           if(obj!=nil)[selectedPeople setArray:(NSArray*)obj];

       }

       maybeSetViewNil=NO;

    }

注意,receivers和selectedPeople对象要在viewDidLoad方法中初始化,而不能在initWithNibName方法中初始化,否则对一个nil对象赋值是无效的。因为iOS在恢复视图时从loadView方法开始调用,而不是从initWithNibName方法(参考前面的图)。


本文转载自:http://blog.csdn.net/kmyhy/article/details/8314827

粉丝 5
博文 106
码字总数 40808
作品 0
徐汇
私信 提问
继 Android P 首个预览版发布后,谷歌又做了一些改进

谷歌发布了 Android P 首个开发者预览版,新系统的亮点包括通知栏的改进、室内定位的优化、适配类似 iPhone X 的顶部凹槽屏幕设计,和性能改进等。谷歌在后期又做了一些改进,以下是挑出的比...

周其
2018/03/13
2.4K
6
非法的 H1Siri 可能毁了你的 iPhone

据报道,来自中国国内的iOS 越狱研究小组 CD-Team 最近成功将 Siri 移植到 iPhone 4S以外的机种,并在国外越狱界引起不小的反响,其自架服务器被挤爆: CD-Team 的在微博对此事进行了回应: ...

刘凯叁
2011/12/06
1K
0
iPhone X到底哪儿吸引了众多用户?答案:TrueDepth相机!

  报告显示,新手机正面的TrueDepth相机是消费者购买的主要驱动因素,并指出消费者对Face ID的态度是“非常积极的”。   iPhone X一经推出就成为万众瞩目的焦点。从首周预定和之后话题热...

镁客网
2017/12/25
0
0
iPhone XS / XS Max 十大外媒评价结集!拍摄能力最让人难忘?

随着 Apple 2018 旗舰手机 iPhone XS、iPhone XS Max 正式开卖日子愈来愈近,世界各地不少媒体都撰写了 iPhone XS、iPhone XS Max 的开箱测试文章,当中的评价或能成为大家购买新 iPhone 与否...

小七里外
2018/09/19
0
0
UIImagePickerController在iso8sdk下的问题

问题有两个,我是用最最简单来测试的。 1.Received memory warning 我拍照后就退出,什么都没干!虽然有警告,内存没有持续增加 而且奇怪的是,它是随机出现的,拍很多次,出现个一次,我只能...

hahashiwo
2014/11/30
3.3K
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 早上儿子问我他是怎么来的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @凉小生 :#今日歌曲推荐# 少点戾气,愿你和这个世界温柔以待。中岛美嘉的单曲《僕が死のうと思ったのは (曾经我也想过一了百了)》 《僕が死の...

小小编辑
29分钟前
25
0
Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
今天
9
0
计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
昨天
6
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
昨天
7
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部