iOS 内存陷阱

iphone开发过程中,代码中的内存泄露我们很容易用内存检测工具leaks 检测出来,并一一改之,但有些是因为ios 的缺陷和用法上的错误,leaks 检测工具并不能检测出来,你只会看到大量的内存被使用,最后收到didReceiveMemoryWarning,最终导致程序崩溃。以下是开发过程中遇到的一些问题和网上的一些资料,总结了一下:

 

一、[UIImage imageNamed:]只适合与UI界面中的贴图的读取,较大的资源文件应该尽量避免使用

用UIImage加载本地图像最常用的是下面三种:

1.用imageNamed方法

[UIImage imageNamed:ImageName];

2.用 imageWithContentsOfFile 方法

NSString *thumbnailFile = [NSString stringWithFormat:@"%@/%@.png", [[NSBundle mainBundle] resourcePath], fileName];
UIImage *thumbnail = [UIImage imageWithContentsOfFile:thumbnailFile];

3. 用initWithContentsFile方法

UIImage *image = [[UIImage alloc] initWithContentsOfFile:filePath]

 

第一种方法为常见方法,利用它可以方便加载资源图片。用imageNamed的方式加载时,会把图像数据根据它的名字缓存在系统内存中,以提高imageNamed方法获得相同图片的image对象的性能。即使生成的对象被 autoReleasePool释放了,这份缓存也不释放。而且没有明确的释放方法。如果图像比较大,或者图像比较多,用这种方式会消耗很大的内存。

第二种方法加载的图片是不会缓存的。得到的对象时autoRelease的,当autoReleasePool释放时才释放。

第三种方法要手动release掉。不系统缓存。release后立即释放,一般用在封面等图比较大的地方。

 

二、 滑动列表的时候,使用UITableView的reuse机制

iOS 内存陷阱
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
     
    static NSString *CellIdentifier = @"Cell"; 
     
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    } 
iOS 内存陷阱

 

dequeueReusableCellWithIdentifier 方法会把隐藏的界面拿来重用,这样节省很多资源。

 

三、要大量创建局部变量的时候,可以创建内嵌的autorelease pool来及时释放内存

iOS 内存陷阱
int main (int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int i, j;
for (i = 0; i < 100; i++ )
{
 NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
 for (j = 0; j < 100; j++ )
    [NSString stringWithFormat:@"1234567890"];//产生的对象是autorelease的。
 [loopPool release];
}
[pool release];
return (0);
} // main
iOS 内存陷阱

 

详细查看:iPhone/Mac Objective-C内存管理教程和原理剖析(一)基本原理

四、频繁打开和关闭SQLite,导致内存不断的增长

SQLite的数据库本质上来讲就是一个磁盘上的文件,频繁打开和关闭是很耗时和浪费资源的,可以设置SQLite的长连接方式;避免频繁的打开和关闭数据库

 

五、在UITableView 的cellForRowAtIndexPath 代理中不要使用 stringWithFormat 方法

定义一个字符串变量有很多方法,最简单的就是 NSString *str = @“abc”, 还有initWithString、stringWithFormat和stringWithCString等等。大量的字符操作时,不同的方法消耗不同的内存。

以下测试代码转自:http://www.cocoachina.com/bbs/read.php?tid-17652-fpage-9.html

iOS 内存陷阱
//测试机器 2.4 GHz Intel Core 2Duo    2GB 667 MHz DDR2   GCC 4.2
- (void)testStringSpeed:(id)sender { NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init]; [textField setStringValue:@""]; int testi,testnum=10; float c,tm=0.0; for(testi=0;testi){ NSDate *beg=[NSDate date]; int i,n=10; for(i=0;i){ //avg=0.030204 } c=[[NSDate date] timeIntervalSinceDate:beg]; tm+=c; [textField setStringValue:[NSString stringWithFormat:@"%@\n%d=%f",[textField stringValue],testi+1,c]]; } [textField setStringValue:[NSString stringWithFormat:@"%@\navg=%f",[textField stringValue],(float)tm/testnum]]; [pool release]; }
iOS 内存陷阱

由于stringWithFormat 即耗时又耗内存,所以在cellForRowAtIndexPath 绘制cell 的时消耗大量内存和时间,造成界面滑动不流畅。

 

六、关于 colorWithPatternImage 的内存泄露

self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bg.png"]];

此方法用图片来设置view的背景颜色,但是某些设备上会导致内存泄露,详细查看:

http://blog.csdn.net/cococoolwhj/article/details/6942981

http://www.cocoaintheshell.com/2011/01/colorwithpatternimage-memory-usage/

更多相关文章
  • 汽车租赁   任务描述       系统搭建       首先要绑定初始数据 //保存可租用车的集合 Dictionary<string, Vehicle> vehicles=new Dictionary<string,Vehicle>(); //保存租出的车的集合 Dict ...
  • 模板与泛型编程 view plaincopy int compare(const string &v1,const string &v2)   {       if (v1 < v2)       {           return -1;       }       els ...
  • 一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证:   今天是2014年的第一天,按中国辞旧迎新的传统,也作为我2014年第一篇博客,我想开篇前要总结下2013年的技术学习.今 ...
  • 一$.ajax的一般用法 $.ajax({    url:url,                                必须有的,它规定把请求发送到哪个控制器里的方法    type:'POST',                        可选择的,默认是Get    data:da ...
  • 一.介绍 ======== 这篇文档旨在介绍如何安装配置基于2台服务器的MySQL集群.并且实现任意一台服务器出现问题或宕机时MySQL依然能够继续运行. 注意! 虽然这是基于2台服务器的MySQL集群,但也必须有额外的第三台服务器作为管理节点,但这台服务器可以在集群启动完成后关闭.同时需要注意的是 ...
  • 易网科技讯 7月9日消息,特斯拉中国区发言人今天发布官方声明,声称中国监管部门已经在两个单独的案件中撤销了占宝生不当获得的商标,占宝生挑战两个商标撤销决定的行政诉讼注将失败.本月3日,占宝生曾向法院提起诉讼,要求特斯拉关闭在中国的汽车展厅.服务中心和增压设施,并向他支付2390万人民币(合390万美 ...
一周排行
  • 文|吕静BAT(百度.腾讯.阿里巴巴)巨头已经悉数进入打车市场,但操盘方式却各不相同.12月17日,百度宣布与硅谷新兴创业公司Uber签署战略合作及投资协议,Uber接受百度战略投资,双方将在技术创新.开拓国际化市场 ...
  • 每经记者 黄俊玲 发自北京除了传出将联手百度.腾讯成立一家新的电子商务公司外,万达集团已将悄悄将触角伸向保险业.<每日经济新闻>记者昨日从保险业内获悉,今年6月曾在北京产权交易所挂牌转让的国电电力持有的百 ...
  •             对于Listview的分组我们再熟悉不过了,因为Android自带的通讯录中的联系人信息就是使用的ListView分组,最近项目中用到了这个功能.所以趁着周末有时间,也更新下一篇这样的博客,希 ...
  • 下面是我用javap来反组译程序1的示范: C:> javap -c -classpath . Singleton Compiled from MyMain.java class Singleton exten ...
  • Mysql(Replication)的实现   个人需要做一个小工程,需要将3台Mysql服务器的数据进行同步操作,经过上网查资料,并进行了实际操作完成了基本构思.           首先准备了3台Centos6. ...
  • 微软正着手关闭新闻组,并鼓励用户迁移到论坛.软件巨人选择了一条更容易控制垃圾帖子的途径.微软正逐步淘汰其管理的2000多个公开的新闻组和2200个私有新闻组,到2010年6月,它们将会迁移到TechNet.MSDN和 ...
  • ADSL的使用,已经普及到家家户户了.随着它的使用伴随着的问题也不少.这里我们就讲解一下ADSL掉线的问题.由于ADSL是电话铜线承载的一种宽带接入技术,电话线传输质量的优劣,直接影响到ADSL宽带的使用.在诸多的A ...
  • DOM 动画是一个极好的 JavaScript 库,用来在页面的 DOM 注释中显示小的 ASCII 动画.这对于那些检查你的代码的人是一个小彩蛋,仅此而已.它是一个独立的库,不依赖 jQuery 或者其它库,所以使 ...
  • 系统默认将带宽的20%用于作浏览器交互使用,如果未配置系统默认带宽限制是20%这样一来我们就可以充分利用全部的宽带资源了,具体破解步骤如下,感兴趣的朋友可以参考下哈 按键盘“Win+R”键,再出来的“运行”对话框中输 ...
  • 算法设计例题:主元素(随机算法) memory limit: 5000KB    time limit: 1000MS accept: 1    submit: 5 Description 设T[1:n]是一个含有n ...