zoukankan      html  css  js  c++  java
  • 转:imageNamed和dataWithContentsOfFile的区别

    最近老是受iphone内存问题的困扰,找了些资料,现在贴出了两篇经典的博文。博文如下:

    转载自:http://blog.csdn.net/hj2060/article/details/6925926

    最近做一个写真书,由于加载大量的图片,内存溢出,程序崩溃,却不报任何错误或者警告。

           用xcode的instrument工具查看内存使用情况时,发现程序使用内存情况很稳定维持在1.3M左右,也没有内存泄漏。那么问题来了,程序无故退出肯定是内存溢出了,而instrument并显示没有溢出(一般单个程序内存消耗唯20M左右会发警告,30M程序崩溃退出)。所以一直在想是不是哪个地方忘记释放内存了,经过仔细检查,并不存在没有释放的内存啊,纠结了一天。最后终于找到问题所在了,是[UIImage imageNamed@""]在搞鬼;

          翻看了一些网上资料http://www.cocoachina.com/bbs/simple/?t36896.html,总结一下UIImage的内存使用及管理

    用UIImage加载图像的方法很多,最常用的是下面两种:

    1.用imageNamed函数

    复制代码
    1. [UIImage imageNamed:ImageName];


    2.用NSData的方式加载,例如:

    复制代码
    1. NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];
      NSData *image = [NSData dataWithContentsOfFile:filePath];
      [UIImage imageWithData:image];



    由于第一种方式要写的代码比较少,可能比较多人利用imageNamed的方式加载图像。其实这两种加载方式都有各自的特点。

    1)用imageNamed的方式加载时,系统会把图像Cache到内存。如果图像比较大,或者图像比较多,用这种方式会消耗很大的内存,而且释放图像的内存是一件相对来说比较麻烦的事情。例如:如果利用imageNamed的方式加载图像到一个动态数组NSMutableArray,然后将将数组赋予一个UIView的对象的animationImages进行逐帧动画,那么这将会很有可能造成内存泄露。并且释放图像所占据的内存也不会那么简单。但是利用imageNamed加载图像也有自己的优势。对于同一个图像系统只会把它Cache到内存一次,这对于图像的重复利用是非常有优势的。例如:你需要在一个TableView里重复加载同样一个图标,那么用imageNamed加载图像,系统会把那个图标Cache到内存,在Table里每次利用那个图像的时候,只会把图片指针指向同一块内存。这种情况使用imageNamed加载图像就会变得非常有效。

    2)利用NSData方式加载时,图像会被系统以数据方式加载到程序。当你不需要重用该图像,或者你需要将图像以数据方式存储到数据库,又或者你要通过网络下载一个很大的图像时,请尽量使用imageWithData的方式加载图像。

    无论用哪种方式加载图像,图像使用结束后,一定要记得显示释放内存。

    所以当程序要加载大量图片时赢尽量使用第二种方法。

    下面贴出另一篇博客:

    http://blog.csdn.net/sing_sing/article/details/6707163

    前段时间完成的一个iPad应用,近来测试发现一个问题,在iPad运行大量其他应用程序时很容易出现内容警告而导致程序退出。找了一些资料,发现用起来方便的+ (UIImage *)imageNamed:(NSString *)name,却存在一个很严重的内存释放问题,它所占用的内容不被释放,即使其所在的view已经release了。看完之后一阵后怕,皆因程序中使用UIImage基本都是使用这种方法获取。事不宜迟,马上对代码进行优化。由于手头暂时没有设备测试,测试效果稍候再分析。

    转载一篇很好的文章:

     
    + (UIImage *)imageNamed:(NSString *)name导致的内存问题

    这种方法在application bundle的顶层文件夹寻找名字的图象 , 如果找到图片, 系统缓存图象。图片内容被加载到系统内存中,使用时直接引用到系统内存。 

    所以当图片比较大时,程序使用的内存会迅速上升导致内存警告并退出。 

    特别在使用Interface Builder建立界面时,如果直接拖动UIImageView 并设置image的图片名称。InterfaceBuilder 正是通过UIImage 类的imageName方法加载图片。图片被缓存,导致内存使用较大。且无法释放,即使release掉 UIImageView也无济于事。 

    所以推荐使用+ (UIImage *)imageWithContentsOfFile:(NSString *)path方法加载图片。 

    也可以重载 imageNamed方法。 

    @implementation UIImage(imageNamed_Hack) 

    + (UIImage *)imageNamed:(NSString *)name { 

    return [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] bundlePath], name ] ];


    @end 

    Note: With this override you will not have any cache loading UIImages, if you need this, 

    you will have to implement your own cache. 

    Tip: If your applications use much image processing, consider to use de PhotoshopFramework 

    for iPhone. Check here: http://sourceforge.net/projects/photoshopframew/

    转:http://blog.csdn.net/kobbbb/article/details/8654707

  • 相关阅读:
    [BJOI2019] 光线
    C# 从零开始写 SharpDx 应用 笔刷
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    PowerShell 拿到显卡信息
    PowerShell 拿到显卡信息
    win10 uwp 如何使用DataTemplate
    win10 uwp 如何使用DataTemplate
  • 原文地址:https://www.cnblogs.com/ygm900/p/3117140.html
Copyright © 2011-2022 走看看