网络图片显示大体步骤:

1、下载图片;

2、图片处理(裁剪,边框等);

3、写入磁盘;

4、从磁盘读取数据到内核缓冲区;

5、从内核缓冲区复制到用户空间(内存级别拷贝);

6、解压缩为位图(耗cpu较高);

7、如果位图数据不是字节对齐的,CoreAnimation会copy一份位图数据并进行字节对齐;

8、CoreAnimation渲染解压缩过的位图。

以上4、5、6、7、8步是在UIImageView的setImage时进行的,所以默认在主线程进行(iOS UI操作必须在主线程执行)。

一些优化思路:

异步下载图片;

image解压缩放到子线程;

使用缓存(包括内存级别和磁盘级别);

存储解压缩后的图片,避免下次从磁盘加载的时候再次解压缩;

减少内存级别的拷贝(针对第5点和第7点);

良好的接口(比如SDWebImage使用category);

Core Data vs 文件存储;

图片预下载。

关于异步图片下载:

fastImageCache主要针对于从磁盘文件读取并展示图片的极端优化,所以并没有集成异步图片下载的功能。这里主要来看看SDWebImage(AFNetWorking的基本类似)的实现方案。

tableView中,异步图片下载任务的管理:

我们知道,tableViewCell是有重用机制的,也就是说,内存中只有当前可见的cell数目的实例,滑动的时候,新显示cell会重用被滑出的cell对象。这样就存在一个问题。

一般情况下在我们会在cellForRow方法里面设置cell的图片数据源,也就是说如果一个cell的imageview对象开启了一个下载任务,这个时候该cell对象发生了重用,新的image数据源会开启另外的一个下载任务,由于他们关联的imageview对象实际上是同一个cell实例的imageview对象,就会发生2个下载任务回调给同一个imageview对象。这个时候就有必要做一些处理,避免回调发生时,错误的image数据源刷新了UI。

SDWebImage提供的UIImageView扩展的解决方案:

imageView对象会关联一个下载列表(列表是给AnimationImages用的,这个时候会下载多张图片),当tableview滑动,imageView重设数据源(url)时,会cancel掉下载列表中所有的任务,然后开启一个新的下载任务。这样子就保证了只有当前可见的cell对象的imageView对象关联的下载任务能够回调,不会发生image错乱。

同时,SDWebImage管理了一个全局下载队列(在DownloadManager中),并发量设置为6.也就是说如果可见cell的数目是大于6的,就会有部分下载队列处于等待状态。而且,在添加下载任务到全局的下载队列中去的时候,SDWebImage默认是采取LIFO策略的,具体是在添加下载任务的时候,将上次添加的下载任务添加依赖为新添加的下载任务。

[wself.downloadQueue addOperation:operation];

        if (wself.executionOrder == SDWebImageDownloaderLIFOExecutionOrder) {

            // Emulate LIFO execution order by systematically adding new operations as last operation's dependency

            [wself.lastAddedOperation addDependency:operation];

            wself.lastAddedOperation = operation;

        }

另外一种解决方案是:

imageView对象和图片的url相关联,在滑动时,不取消旧的下载任务,而是在下载任务完成回调时,进行url匹配,只有匹配成功的image会刷新imageView对象,而其他的image则只做缓存操作,而不刷新UI。

同时,仍然管理一个执行队列,为了避免占用太多的资源,通常会对执行队列设置一个最大的并发量。此外,为了保证LIFO的下载策略,可以自己维持一个等待队列,每次下载任务开始的时候,将后进入的下载任务插入到等待队列的前面。

iOS异步任务一般有3种实现方式:

  • NSOperationQueue

  • GCD

  • NSThread

这几种方式就不细说了,SDWebImage是通过自定义NSOperation来抽象下载任务的,并结合了GCD来做一些主线程与子线程的切换。

iOS异步图片加载优化与常用开源库分析的更多相关文章

  1. YYWebImage——iOS异步图片加载框架

    本文转载至 http://www.mobile-open.com/2015/86582.html   YYWebImage 是一个异步图片加载框架 (YYKit 组件之一). 其设计目的是试图替代 S ...

  2. iOS Cell异步图片加载优化,缓存机制详解

    最近研究了一下UITbleView中异步加载网络图片的问题,iOS应用经常会看到这种界面.一个tableView上显示一些标题.详情等内容,在加上一张图片.这里说一下这种思路. 为了防止图片多次下载, ...

  3. Android高效异步图片加载框架

    概述 Android高效异步图片加载框架:一个高效的异步加载显示的图片加载框架,同时具备图片压缩,缓存机制等特性. 详细 代码下载:http://www.demodashi.com/demo/1214 ...

  4. Android 框架修炼-自己开发高效异步图片加载框架

    一.概述 目前为止,第三方的图片加载框架挺多的,比如UIL , Volley Imageloader等等.但是最好能知道实现原理,所以下面就来看看设计并开发一个加载网络.本地的图片框架. 总所周知,图 ...

  5. Swift - 表格图片加载优化(拖动表格时不加载,停止时只加载当前页图片)

    列表的单元格中包含有图片在开发中很常见.通常我们可以直接在tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIn ...

  6. android 图片加载优化,避免oom问题产生

    1,及时回收bitmap,在activity的onstop()和onDestory()里面调用如下代码进行bitmap的回收: // 先判断是否已经回收 if(bitmap != null & ...

  7. web前端图片加载优化,从图片模糊到清晰的实现过程

    在网页图片显示的时候,会发现许多网站采用了先模糊,然后在慢慢清晰的过程,这样的加载用户体验是比较好的,那么如何实现呐? 默认加载2张图片,一张缩略图,一张原图,当打开网页的时候默认只显示缩略图,然后我 ...

  8. 转: listview异步图片加载之优化篇(android)

    Listview异步加载之优化篇 关于listview的异步加载,网上其实很多示例了,总体思想差不多,不过很多版本或是有bug,或是有性能问题有待优化.有鉴于此,本人在网上找了个相对理想的版本并在此基 ...

  9. FLAnimatedImage -ios gif图片加载框架介绍

    简介 FLAnimatedImage 是 Flipboard 团队开发的在它们 App 中渲染 GIF 图片使用的库. 后来 Flipboard 将 FLAnimatedImage 开源出来供大家使用 ...

随机推荐

  1. ubuntu 安装 open in teminal

    sudo apt-get install nautilus-open-terminalnautilus -q

  2. CSS Hack技术详解,支持IE 6-11、Chrome、FireFox、Safari、Opera 6-11、Chrome、FireFox、Safari、Opera6-11、Chrome、FireFox、Safari、Opera6-11、Chrome、FireFox、Safari、Opera

    转自: http://www.365mini.com/page/css-hack-ie-chrome-firefox-safari-opera.htm 当前网络时代,各种各样的网页向我们展示着丰富多彩 ...

  3. C#面试-关于const和readonly(看了一个点赞很多的帖子有感而发!)

    前景提要: 最近大家都在面试,讨论最多.最基础的问题,莫过于“关于const和readonly常见的笔试题剖析”,等等的大牛解析.我就是一个小菜,只不过,有点不敢苟同大牛的意见.废话少说,进入重点. ...

  4. 如何更好辨认House of hello恶搞包的真假

    相信很多朋友都知道houseofhello恶搞包这个品牌,甚至很多朋友都买过,首先呢,她是恶搞包,算自主品牌,它无淘宝店,更没有所谓的香港实体店.因为这品牌受到广大朋友的狂热,导致无数仿品的出现,淘宝 ...

  5. JSP 表单request内容

    1. 表单request内容的获取 2. request.setCharacterEncoding("utf-8")对request内容进行编码 3. fullformreques ...

  6. Tomcat8 配置Oracle11g数据源

    1:context.xml <Resource name="jdbcoracle" auth="Container" type="javax.s ...

  7. Solr4.6从数据库导数据的步骤

    http://blog.csdn.net/bruce128/article/details/17796705 Solr4.6有从数据库导数据的功能.导入步骤如下: 1.将下载下来的solr4.6的di ...

  8. 有趣的TWinControl.RecreateWnd,并分析在哪些场合使用

    CM_RECREATEWND = CM_BASE + 51; // TWinControl里有对应函数procedure CMRecreateWnd(var Message: TMessage); m ...

  9. 如何给div加一个边框border样式

    如何给div加一个边框样式? 对div盒子加一个边框样式很简单只需要使用border板块样式即可. 一.虚线与实线边框 边框虚线样式:dashed 边框实现样式:solid border:1px da ...

  10. DB_WRITER_PROCESSES与LOG_ARCHIVE_MAX_PROCESSES

    DB_WRITER_PROCESSES Property  Description Parameter type  Integer Default value  1 or CPU_COUNT / 8, ...