美文网首页
SDWebImage学习笔记

SDWebImage学习笔记

作者: 希尔罗斯沃德_董 | 来源:发表于2022-01-11 21:38 被阅读0次

    SDWebImage是什么

    SDWebImage是一个提供了高效的图片异步加载、图片缓存和图片处理等功能的一个第三方开源框架。

    SDWebImage做了什么,怎么做?

    接口设计

    用UIKit相关类的Category封装图片加载的接口。

    图片下载

    图片下载管理器SDImageLoadersManager+NSOperationQueue+自定义NSOperation并重写start、finish、cancel等方法用于管理图片加载队列。

    图片缓存

    缓存图片,分内缓存和磁盘缓存,同时配合着多种缓存策略,以供开发者根据具体业务需求选择使用。

    • 内存缓存使用NSCache+NSMapTable&dispatch_semaphore_t配合使用
    • 磁盘缓存使用NSFileManager+GCD串行队列管理图片文件的读写。
    图片的其他处理。
    • 图片编解码,分生成位图直接解码和渐进式解码两种。
    • 动态图片展示。
    • 图片转换等相关操作。
    • 图片格式判断

    SDWebImage为什么要这么做?

    接口为什么用Category

    Category封装接口方便调用。

    图片下载队列管理

    NSOperationQueue+自定义NSOperation并重写start、finish等方法用于管理图片加载队列,为了start和finish在一个线程里执行,方便管理,这样外部就只关心队列的本身的本身。

    图片缓存机制

    分内缓存和磁盘缓存。配合各种缓存策略实现。

    • 内存缓存,NSCache+NSMapTable配合使用
      NSCache是真正的缓存,NSMapTable只是弱引用,当收到内存警告时移除的是NSCache的引用,此时如果图片对象在页面在被引用,内存还是会存在的,依然可以通过NSMapTable来访问。
    • 磁盘缓存,磁盘缓存使用NSFileManager管理图片文件 + GCD串行队列保证安全。

    配合着多种缓存策略,开发者可以根据业务需求自行选择,同时根据自身app性能做做一些自定义的优化。内存缓存大小和过期时间都可以自定义,收到内存警告清理掉NSCache,只保留NSMapTable的弱引用。

    内存优化
    • 针对UITableView内存优化,设置加载低优先级,这样下载队列和解码队列优先级会变低,在ScrollView滚动减速时加载。避免了在页面发生交互时加载图片,减轻CPU压力。
    • 大图优化,对于大图可以选择不缓存图片,同时可以在解码时设置图片的目标尺寸,减少内存占用。同时动图解码时使用渐进式解码,避免同时解码造成内存暴增。
    图片的其他处理。
    • 两种解码:
      解码有两种方式,通过异步队列调用管理解码任务。实现原理NSOperationQueue&addOperationWithBlock+maxCount = 1?为了可以取消任务?downloader->coderQueue->Block(解码操作)
      解码1-直接生成位图解码:downloader->coderQueue->CGImageRef-> CGBitmapContextCreate(CGContextRef)->CGContextDrawImage->CGBitmapContextCreateImage

    1、创建一张位图的上下文Context=CGBitmapContextCreate
    2、绘制图片到这个CGContextDrawImage(Content)
    3、通过上下文Content生成图片newImageRef=CGBitmapContextCreateImage(Content)

    核心代码如下:

        CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host;
        bitmapInfo |= hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;
        CGContextRef context = CGBitmapContextCreate(NULL, newWidth, newHeight, 8, 0, [self colorSpaceGetDeviceRGB], bitmapInfo);
        if (!context) {
            return NULL;
        }
        
        // Apply transform
        CGAffineTransform transform = SDCGContextTransformFromOrientation(orientation, CGSizeMake(newWidth, newHeight));
        CGContextConcatCTM(context, transform);
        CGContextDrawImage(context, CGRectMake(0, 0, width, height), cgImage); // The rect is bounding box of CGImage, don't swap width & height
        CGImageRef newImageRef = CGBitmapContextCreateImage(context);
        CGContextRelease(context);
    

    解码2-渐进式解码:

    CGImageSourceCreateIncremental->CGImageSourceUpdateData->CGImageSourceCreateImageAtIndex
    1、CGImageSourceCreateIncremental创建一个空的CGImageSourceRef
    2、图片数据更新之后调用CGImageSourceUpdateData将图片数据ImageData更新到CGImageSourceRef中
    3、CGImageSourceCreateImageAtIndex生成CGImageRef

    • 动图展示。通过CADisplayLink利用屏幕刷新频率和Runloop的空闲时间显示动图,提高性能。
    • 圆角。UIGraphicsImageRenderer(imageWithActions)->UIBezierPath(贝塞尔曲线)->UIGraphicsImageRendererContext。UIGraphicsImageRendererContext可以复用渲染上下文,提高效率。
    • 图片格式判断。通过图片数据的第一个字节判断或者通过CGImageSourceRef获取图片格式

    相关文章

      网友评论

          本文标题:SDWebImage学习笔记

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