由一张jpg引发的深究

作者: 鐵甲陳小寶 | 来源:发表于2016-07-08 01:17 被阅读145次

    今天项目组一个同事将jpg放到了resource文件夹中,其实平常我们的图片资源文件全是在xcassets里面,于是我问他为什么这样放,他说将jpg的图片放到xcassets里面,用文件名获取不到。

    UIImage *image = [UIImage imageNamed:@"Twilight1"];
    

    就想这样。
    那到底这是问什么喃?

    探寻

    来,我们从这个方法进去看看,

    imageName.png

    可以看到api reference中提到了那么这个参数;说到,如果你是第一次调用这个图片,这个方法会到main bundle中去寻找这个名字的图片,但是为什么是第一次喃?

    后面才是这一次的重点,如果是PNG格式的图片,那么你可以忽略扩展名,但是其他格式,你需要加上拓展名,这就解释了为什么获取不到这张jpg图片。

    而且你在xcassets中的图片是用imageWithContentsOfFile方法获取不到的,因为xcassets在打包后会变成car格式的压缩包。


    car.png

    所以你用并不能用NSbundle的pathForResource等方法获取到该图片的路径。所以,如果你需要用imageWithContentsOfFile方法,你就需要将图片放到bundle中,而不是xcassets。
    于是,你应该这么写

    UIImage *image = [UIImage imageNamed:@"Twilight1.jpg"];
    

    第一次?

    上面提到了第一次获取调用这张图片,为什么是第一次喃?相信大部分iOS程序猿都知道,因为这个函数会将获取到的图片存到缓存中,下次再次调用,会直接取到该图片的缓存。文档也确实这样写道:


    缓存.png

    不过凡事讲证据,证据来也:


    cache.png
    可以看到,在后面确实调用了NSCache的存储方法。

    然后文档还说到:

    The system may purge cached image data at any time to free up memory. Purging occurs only for images that are in the cache but are not currently being used.
    

    就是说,系统会有可能在任何时候清除内存中缓存图片,在使用中的不受影响。根据YY大神的测试:“据我观察,在图片解码后,App 第一次退到后台和收到内存警告时,该图片的缓存才会被清空,其他情况下缓存会一直存在。”
    那么那些方法不会造成图片的缓存喃?来,看看文档:

    This method does not cache the image object.
    • imageWithContentsOfFile:
    • imageWithData:scale:
    • imageWithCGImage:
    • imageWithCGImage:scale:orientation:
      这4种方法在文档中都写到不会造成缓存。
      看看执行的情况:


      noCache.png

      可以看到是真的没有进行系统缓存。

    图片的decode

    最近南峰子大大的微博发出的关于UIImage的知识小集中提到了UIImage的解码,有兴趣的可以去看看,并且自己动手试试看。

    相关文章

      网友评论

        本文标题:由一张jpg引发的深究

        本文链接:https://www.haomeiwen.com/subject/kxgljttx.html