SDWebImage(5.6.1)源码阅读

520 阅读2分钟

SDWebImage调用过程

1.执行UIImageView+WebCache里面加载图片方法,最终调用UIImageView+WebCache里面这个方法

- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(SDWebImageOptions)options
                   context:(nullable SDWebImageContext *)context
                  progress:(nullable SDImageLoaderProgressBlock)progressBlock
                 completed:(nullable SDExternalCompletionBlock)completedBlock;
                 
                 

2. UIImageView+WebCache里面方法会走到UIView+WebCache里面,因为还有UIButton的图片加载,因此公共方法需要写到父类UIView+WebCache里


// 摘取核心、简要代码

- (void)sd_internalSetImageWithURL:(nullable NSURL *)url
                  placeholderImage:(nullable UIImage *)placeholder
                           options:(SDWebImageOptions)options
                           context:(nullable SDWebImageContext *)context
                     setImageBlock:(nullable SDSetImageBlock)setImageBlock
                          progress:(nullable SDImageLoaderProgressBlock)progressBlock
                         completed:(nullable SDInternalCompletionBlock)completedBlock {
   
   // 网络加载图片是延迟操作, 
   // tableView列表上加载图片,在滚动的范围,图片还没有下载完成,或者正在下载,导致一张图片多次下载可能会出错,所以每次都先取消
   
   // 取消当前下载操作                          
   [self sd_cancelImageLoadOperationWithKey:validOperationKey];      
   
   if (url) {  //url存在情况
   
   // 获取 manager 实例对象
   // manager实例初始化过程,会对其它一些类做一些初始化工作
   
    SDWebImageManager *manager = context[SDWebImageContextCustomManager];
    if (!manager) {
        manager = [SDWebImageManager sharedManager];
    }
    
    //根据url 开始加载结果
    id <SDWebImageOperation> operation = [manager loadImageWithURL:[NSURL URLWithString:@""] options:options context:context  progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
        
          //回调结果  
          
    //这是一个用来回到结果的block      
    SDWebImageNoParamsBlock callCompletedBlockClojure = ^{
     
     if (!self) { return; }
      completedBlock(image, data, error, cacheType, finished, url);
     };
     
     //异步回调结果
    dispatch_main_async_safe(callCompletedBlockClojure);
            
    }];
    
    //把下载操作加入到字典里面去
    [self sd_setImageLoadOperation:operation forKey:validOperationKey];
    
     
     
    }else { //url不存在情况
    
      // 回调一个错误的结果
         
    }
   
  }

3. SDWebImageManager类里面方法

// 初始化工作
//通过单例会走到初始化方法里

- (nonnull instancetype)init {
   //缓存对象的实例化,也是保证全局只有一个
    _imageCache = cache;
  // 下载对象的实例化
    _imageLoader = loader;
 //图片下载失败集合容器的创建    
  _failedURLs = [NSMutableSet new];
  _failedURLsLock = dispatch_semaphore_create(1);
  // 运行操作集合创建
  _runningOperations = [NSMutableSet new];
  _runningOperationsLock = dispatch_semaphore_create(1);
    
}



// 下载图片方法
- (SDWebImageCombinedOperation *)loadImageWithURL:(nullable NSURL *)url
                                          options:(SDWebImageOptions)options
                                          context:(nullable SDWebImageContext *)context
                                         progress:(nullable SDImageLoaderProgressBlock)progressBlock
                                        completed:(nonnull SDInternalCompletionBlock)completedBlock  {
       
    // 对url进行容错处理  
    // 如果是NSString类型转换为NSURL   
     if ([url isKindOfClass:NSString.class]) {
        url = [NSURL URLWithString:(NSString *)url];
    }                                        
    
    // 如果传进来NSNull,可能会导致应用程序崩溃,转换为nil
     if (![url isKindOfClass:NSURL.class]) {
         url = nil; //容错
    }   
    
    
    //容错处理完之后,开始进行下一步
    
    //创建一个操作
     SDWebImageCombinedOperation *operation = [SDWebImageCombinedOperation new];
                                            
                                            
                                            
                                        }