SDWebImage Note

作者: StanOz | 来源:发表于2016-08-11 21:52 被阅读106次

    这是笔者学习 SDWebImage 源码时的笔记,对它有着很深的怨念呢。😊

    功能

    SDWebImage 提供的主要功能如下:

    • 提供异步图片(后台)下载并保证不阻塞主线程;
    • 支持内存和磁盘双缓存策略,保证同一 url 不会请求多次;
    • 支持 WebP/Gif 等格式;

    结构

    SDWebImageManager 协调 SDImageCacheSDWebImageDownloader 这两个模块的工作,内部使用自定义的 SDWebImageCombinedOperation 直接或间接引用对图片的缓存查询以及下载的操作,便于取消。

    sdwebimg_struct.png

    原理

    对于每一次的图片下载操作,imageManager 让 cacheManager 去缓存中查找,由于在内存缓存中查找的速度很快,所以只在对磁盘缓存查询时,才异步在 ioQueue 中执行查询任务,避免阻塞主线程。查询完成之后,imageDownloader 开始工作,如果 “所需缓存不存在/缓存过期/ SDWebImageRefreshCached 开启”,downloader 就会产生一个 loaderOperation(继承于 NSOperation)放入 downloadQueue,等待启动。一旦操作启动, urlConnection 去下载图片数据。这个操作是在子线程去执行的,为了能保证接收到 urlConnection 回调回来的数据,不能让这个线程把 -start 内的的代码执行完,就结束自己的生命,所以需要 runLoop 去驱动线程接收数据,直到 “数据接收完成/发生错误/主动取消操作” 才停止这个runLoop,接收完成了之后发送通知并执行预设的 block。

    性能

    SDWebImage 的源码中有两个地方提到 ‘performance’ 这个词:

    • shouldDecompressImages 这个 flag 中的注释,提到了如果开启了这个 flag 可以提高性能,换来的代价是消耗更多的内存。要弄懂 shouldDecompressImages 的意义必须先了解图片从读取到显示的过程

        1. 从磁盘拷贝数据到内核缓冲区
        2. 从内核缓冲区复制数据到用户空间
        3. 生成 UIImageView,把图像数据赋值给 UIImageView
        4. 如果图像数据为未解码的 PNG/JPG,解码为位图数据
        5. CATransaction 捕获到 UIImageView layer 树的变化
        6. 主线程 Runloop 提交 CATransaction,开始进行图像渲染
            6.1 如果数据没有字节对齐,Core Animation 会再拷贝一份数据,进行字节对齐
            6.2 GPU处理位图数据,进行渲染
      

    在这个过程中我们可以看到,如果我们直接将未经解码的图像数据传递给 UIImageView 对象,那么该对象就会在主线程中去解码图像数据,在图片特别大的情况下耗时相应的也会特别多,因此 SDWebImage 在解码图片这一步上做了优化,放到了子线程中执行,这样拖动 tableView 的时候不至于阻塞主线程。

    • SDWebImageRefreshCached 这个 flag 中的注释提到,使用 NSURLCache 而非 SDWebImageCache 会降低一点性能。因为对于每个 HTTP 请求,我们都可以对 NSURLCache(如果使用)设置相应的缓存策略。通常在响应返回之后,客户端缓存这一份数据,通过响应头的 Expires, Cache-Control 等字段决定这份缓存什么时候过期。如果缓存过期,HTTP 允许缓存端发送条件 GET 请求到服务器,询问这份缓存的内容是否仍然是“新鲜的”。如果服务器对原来客户端缓存过的数据进行了更改,那我们就有必要从服务器中再取一份数据。综上,如果某个 url 对应的资源时常发生变动,那么我们应该启用 NSURLCache,而图片通常是静态的,所以启用 SDWebImageCache 可以跳过询问缓存是否新鲜这个步骤,提高一点查询速度。

    总结

    有更好的网络图片加载库吗?当然,据闻 FastImageCache 和 YYWebImage 做的优化似乎更多。

    然而现在只能等有空的时候再膜一番了。

    相关文章

      网友评论

        本文标题:SDWebImage Note

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