`
GeekDuke
  • 浏览: 2253 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

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机制


- (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];
    }


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

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


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 < 100000; j++ )
    [NSString stringWithFormat:@"1234567890"];//产生的对象是autorelease的。
[loopPool release];
}
[pool release];
return (0);
} // main


详细查看: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


//测试机器 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=10000000;
        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];
}


由于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/
分享到:
评论

相关推荐

    ios开发内存管理

    ios移动开发的内存管理ppt,讲的不错,你值得拥有

    iOS开发内存分配图示

    iOS开发学习笔记之内存分配图示.虚拟内存分配图示

    ios应用源码之如何获取ios型号,版本,内存,磁盘,mac地址等信息的sample代

    ios应用源码之如何获取ios型号,版本,内存,磁盘,mac地址等信息的sample代码

    ios开发技巧总结.docx

    ios开发 iOS开发涵盖了许多方面,以下是一些关键的开发技巧和最佳实践: 熟悉Swift或Objective-C:Swift是苹果...内存管理:理解ARC(Automatic Reference Counting)自动引用计数机制,避免内存泄漏和循环引用问题。

    iOS开发规范.pdf

    iOS 基本技术规范(基本语法使用规范、基本内存使用规范 、声明周期使用规范、项目工程结构基本使用规范、代码组织规范、注意的要点及其格式规范),

    iOS内存泄漏检测器

    使用运行时机制可以对任意一个NSObject对象及其子类 在任何类中添加 dealloc监测 在开发过程中可以检测循环引用等内存泄漏问题 方便自测 提高代码健壮性

    iOS开发规范(蔡令).docx

    iOS 基本技术规范(基本语法使用规范、基本内存使用规范 、声明周期使用规范、项目工程结构基本使用规范、代码组织规范、注意的要点及其格式规范),

    ios内存泄漏检测工具

    用于检测iOS内存泄漏,当每个页面结束时,能显瘦该页面的内存泄漏情况。这是一个很好的开发小工具

    iOS开发缓存机制之—内存缓存机制

    这篇文章将介绍一下如何在iOS设备中进行缓存,本文先介绍一下将内容缓存到内存中,下一篇文章就介绍一下在iOS磁盘上缓存内容。

    庄延军《iOS内存管理及优化》

    庄延军《iOS内存管理及优化》,一本不错的关于ios内存管理的书。

    Swift-OOMDetector是腾讯开源的一个iOS的内存监控组件

    iOS的内存监控组件,为您提供OOM监控,内存分配监控,内存泄漏检测等功能。

    IOS开发-开发心得-技术栈-初学者-学习路线-开发原则

    这篇开发原则涵盖了苹果iOS开发的关键要点和注意事项。它强调了深入了解iOS生态系统、精通编程语言、熟悉开发工具、掌握核心框架、适配不同设备和屏幕、遵循设计准则、注重性能和内存管理、测试和调试、遵循App ...

    ios-内存管理编程指南

    ios-内存管理编程指南,主要用于苹果手机和ipad系列开发。

    ios iphone开发-内存管理

    ios iphone开发-内存管理 所有权是iPhone内存管理的核心思想,对象的所有者负责在使用完对象后进行释放。一个对象可以有多个所有者,当它没有所有者时将被设置为取消分配(deallocation)

    iOS开发 常见的崩溃闪退原因(12点)1

    1. 字典的key或value为nil,字典的key只要为nil任何写法定会崩, 2. 数组越界 3. 内存溢出或泄露,分为下个 4. 遍历数组时,对数组进操作

    IOS内存管理Delegate与IOS下Speex语音压缩开发

    IOS的内存管理详解。 Delegate具体详解,使用流程。 Speex的语音压缩技术。 完整详细解读。40页,通俗简单,深入浅出,并有代码示例ppt。

    彻底解决reactnative在iOS端内存过高的问题

    RSListView 是彻底解决 react-native 长列表在 iOS 端内存过高问题的 ListView,是对 ListView的封装(参照了SGListView,但SGListView存在的问题是容易丢掉renderRow的视图,RSListView 是 SGListView 的一个改良...

    ios 单元格重用问题

    UITableView中的cell可以有很多,一般会通过重用cell来达到节省内存的目的:通过为每个cell指定一个重用标识符(reuseIdentifier),即指定了单元格的种类,当cell滚出屏幕时,会将滚出屏幕的单元格放入重用的queue中,当...

    尚乘教育_iOS_开发培训课程

    尚乘教育_iOS_开发培训课程_03_使用_ARC_管理内存.pdf 尚乘教育_iOS_开发培训课程_04_Delegation_and_Core_Location.pdf 尚乘教育苹果_iOS_开发培训课_06_Subclassing_UIView_and_UIScrollView.pdf 尚乘教育苹果_iOS...

Global site tag (gtag.js) - Google Analytics