zoukankan      html  css  js  c++  java
  • SDWebImage源码解析

    SDWebImage是通过类别的方式给UIImageview 和UIButton 等类进行扩展,方便用户下载图片并渲染到视图上的开源库,解读该开源代码的时候SDWebImage的版本是

    3.7.5。

    0x 01、 动态关联一个NSURL的属性到UIImageView,仅用于应用层需要返回sd_imageURL的时候读取,代码如下:

     objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 

    0x 02 、使用一个SDWebImageManager的单例.sharedManager开启一个SDWebImageCombinedOperation 操作下载,开启该下载之前,先去之前缓存过的下载失败的

     NSMutableSet *failedURLs集合里去查找,当前要下载的url是否被包含,若被包含,则直接返回失败。

    0x 03 、若0x 02没有返回,则把SDWebImageCombinedOperation加入到一个runningOperations的数组里,用[url

    absoluteString]作为key值,去SDImageCache里查询。以key为关键字的图片。

    1 [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType){}] 

    0x 04、在SDImageCache查询的时候,先去查询以key为关键字的图片是否存在内存缓中,若内存缓存中做存在,则返回查找成功。

    1  UIImage *image = [self imageFromMemoryCacheForKey:key];
    2     if (image) {
    3         doneBlock(image, SDImageCacheTypeMemory);
    4         return nil;
    5     }

    0x 05、若内存缓存中没有找到,则到硬盘存储中去继续查询关键字为key的图片,在硬盘里查找的时候,启动一个GCD的串行队列_ioQueue查找,若没有查找到则返回查找失败,若查找到,先把查找到的图片缓存到内存中去,再返回。

    关键代码:

     1 // 此处创建一个串行的GCD队列查找硬盘中的图片
     2  _ioQueue = dispatch_queue_create("com.hackemist.SDWebImageCache", DISPATCH_QUEUE_SERIAL);
     3 
     4 NSOperation *operation = [NSOperation new];
     5     dispatch_async(self.ioQueue, ^{
     6         if (operation.isCancelled) {
     7             return;
     8         }
     9 
    10         @autoreleasepool {
    11             UIImage *diskImage = [self diskImageForKey:key];
    12             //缓存查找到的图片到内存中去
    13             if (diskImage && self.shouldCacheImagesInMemory) {
    14                 NSUInteger cost = SDCacheCostForImage(diskImage);
    15                 [self.memCache setObject:diskImage forKey:key cost:cost];
    16             }
    17            //返回查找到的图片
    18             dispatch_async(dispatch_get_main_queue(), ^{
    19                 doneBlock(diskImage, SDImageCacheTypeDisk);
    20             });
    21         }
    22     });

    0x 06、 若内存和硬盘中都没有查找到图片,则在SDWebImageDownloader里启动一个SDWebImageDownloaderOperation的

    operation开始下载,SDWebImageDownloaderOperation类继承自NSOperation类,所以可以检查一下下载的时候是否是先进先出,如果不是,则把最后一次添加的

    operation添加依赖到当前operation之后执行。

    关键代码:

     1      operation = [[wself.operationClass alloc] initWithRequest:request
     2                                                           options:options
     3                                                          progress:^(NSInteger receivedSize, NSInteger expectedSize) {}];//启动一个operation 任务
     4 
     5          //把一个downloadQueue任务添加到一个NSOperationQueue里去
     6         [wself.downloadQueue addOperation:operation];
     7         //若不是先进先出的任务,则添加前一个任务依赖后一个任务,一般情况下默认是先进先出,不用处理
     8         if (wself.executionOrder == SDWebImageDownloaderLIFOExecutionOrder) {
     9             // Emulate LIFO execution order by systematically adding new operations as last operation's dependency
    10             [wself.lastAddedOperation addDependency:operation];
    11             wself.lastAddedOperation = operation;
    12         }

    0x 07、 在SDWebImageDownloaderOperation 内部启动一个NSURLConnection请求来下载图片。下载完成之后,解码图片,然后缓存到内存和硬盘中去(是否缓存到硬盘中去取决于用户设置的options选项)。

    关键代码:

       if (!image.images) {
                    if (self.shouldDecompressImages) {
                        image = [UIImage decodedImageWithImage:image];
                    }
                }//解码图片
    //缓存图片到内存和硬盘中去。
      [self.imageCache storeImage:downloadedImage recalculateFromImage:NO imageData:data forKey:key toDisk:cacheOnDisk];

    0x 08 返回图片给主线程,刷新视图控件。

    补充一下,一般图片默认缓存在目录下(Library/Caches/default)

    1   NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    2     return [paths[0] stringByAppendingPathComponent:fullNamespace];
  • 相关阅读:
    Java vs Python
    Compiled Language vs Scripting Language
    445. Add Two Numbers II
    213. House Robber II
    198. House Robber
    276. Paint Fence
    77. Combinations
    54. Spiral Matrix
    82. Remove Duplicates from Sorted List II
    80. Remove Duplicates from Sorted Array II
  • 原文地址:https://www.cnblogs.com/yanyan1119/p/5311985.html
Copyright © 2011-2022 走看看