美文网首页
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