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];
  • 相关阅读:
    QT4.7.1 + VS2008 + QT Designer开发流程心得
    SharePoint 2010 托管元数据Bug (跟邮件提醒功能相关.小bug,大问题)
    SharePoint 2010 技巧系列: 控制Ribbon菜单权限(SiteActions的例子)
    发布一个SharePoint 2010 工具(复制,移动文件和文件夹)
    SHarePoint 2010 技巧 列验证 (column Validation)
    SharePoint 2010系列: 教你如何创建Internet 站点一 (设计母版页)
    SharePoint2010 技巧系列:快速开发Ribbon
    SharePoint 2010 技巧: 限制People Picker搜索非站点集内的用户
    SharePoint 2010 技巧系列 启用文档库接收邮件功能
    SharePoint 2010 技巧系列: 文档管理的自动分发功能
  • 原文地址:https://www.cnblogs.com/yanyan1119/p/5311985.html
Copyright © 2011-2022 走看看