【iOS】 使用SDWebImage 定制你的缓存图片

SDWebImage是一个强大的网络图像异步缓存框架,使用非常方便。本章我们介绍如何对SDWebImage下载的网络图像进行定制处理。

一、接口API

SDWebImage 提供了对UIImageViewUIButton异步加载网络图片的UI扩展,你可以在文件UIImageView+WebCacheUIButton+WebCache 中查看具体实现。

我们看下UIImageView扩展的相关实现:

/**
 * Integrates SDWebImage async downloading and caching of remote images with UIImageView.
 */
@interface UIImageView (WebCache)

/**
 * Set the imageView `image` with an `url`.
 * The download is asynchronous and cached.
 * @param url The url for the image.
 */
- (void)sd_setImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT;

/**
 * Set the imageView `image` with an `url` and a placeholder.
 * The download is asynchronous and cached.
 * @param url         The url for the image.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @see sd_setImageWithURL:placeholderImage:options:
 */
- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT;

/**
 * Set the imageView `image` with an `url`, placeholder and custom options.
 * The download is asynchronous and cached.
 * @param url         The url for the image.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @param options     The options to use when downloading the image. @see SDWebImageOptions for the possible values.
 */
- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT;

/**
 * Set the imageView `image` with an `url`, placeholder, custom options and context.
 * The download is asynchronous and cached.
 * @param url         The url for the image.
 * @param placeholder The image to be set initially, until the image request finishes.
 * @param options     The options to use when downloading the image. @see SDWebImageOptions for the possible values.
 * @param context     A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 */
- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(SDWebImageOptions)options
                   context:(nullable SDWebImageContext *)context;

/**
 * Set the imageView `image` with an `url`.
 * The download is asynchronous and cached.
 * @param url            The url for the image.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sd_setImageWithURL:(nullable NSURL *)url
                 completed:(nullable SDExternalCompletionBlock)completedBlock;

/**
 * Set the imageView `image` with an `url`, placeholder.
 * The download is asynchronous and cached.
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                 completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;

/**
 * Set the imageView `image` with an `url`, placeholder and custom options.
 * The download is asynchronous and cached.
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(SDWebImageOptions)options
                 completed:(nullable SDExternalCompletionBlock)completedBlock;

/**
 * Set the imageView `image` with an `url`, placeholder and custom options.
 * The download is asynchronous and cached.
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.
 * @param progressBlock  A block called while image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(SDWebImageOptions)options
                  progress:(nullable SDImageLoaderProgressBlock)progressBlock
                 completed:(nullable SDExternalCompletionBlock)completedBlock;

/**
 * Set the imageView `image` with an `url`, placeholder, custom options and context.
 * The download is asynchronous and cached.
 * @param url            The url for the image.
 * @param placeholder    The image to be set initially, until the image request finishes.
 * @param options        The options to use when downloading the image. @see SDWebImageOptions for the possible values.
 * @param context        A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
 * @param progressBlock  A block called while image is downloading
 *                       @note the progress block is executed on a background queue
 * @param completedBlock A block called when operation has been completed. This block has no return value
 *                       and takes the requested UIImage as first parameter. In case of error the image parameter
 *                       is nil and the second parameter may contain an NSError. The third parameter is a Boolean
 *                       indicating if the image was retrieved from the local cache or from the network.
 *                       The fourth parameter is the original image url.
 */
- (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;

二、基础用法

如果你有使用SDWebImage框架经验,可以直接忽略此部分

本文我们只针对UIImageView , 使用前请导入#import

1.1 异步加载网络图片

通常情况下你可以直接使用获取的图片URL地址加载网络图片,你可以在滚动的列表或者其他需要加载图片的地方调用以下接口

[self.imageView sd_setImageWithURL:[NSURL urlWithString:urlString]];

1.2 设置一个占位图

占位图会优先显示到UIImageView上,当图片加载成功后会替换占位图,占位图的显示时长与第一此加载网络图片进度有关,如果网络图片加载较慢,你可以很明显看到占位图,快则占位图一闪而过,当图片被缓存后,你几乎看不到占位图显示。

[self.imageView sd_setImageWithURL:[NSURL urlWithString:urlString] 
                  placeholderImage:[UIImage imageNamed:@"myPlaceHolder"]];

1.3 添加代理回调

如果你想要在图片加载成功后对做一些额外的处理,你需要配置一下代理回调block:

[self.imageView sd_setImageWithURL:[NSURL urlWithString:urlString] 
                  placeholderImage:[UIImage imageNamed:@"myPlaceHolder"]
                  completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                      if (error) {
                      }
                      else {
                          
                      }
                  }];

1.4 使用Options

SDWebImage 提供了 SDWebImageOptions 缓存选项,你可以根据需要进行动态配置:

1.4.1 失败后重试
[self.imageView sd_setImageWithURL:[NSURL urlWithString:urlString] 
                  placeholderImage:[UIImage imageNamed:@"myPlaceHolder"]
                  options:SDWebImageRetryFailed
                  completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                      if (error) {
                      }
                      else {
                          
                      }
                  }];
1.4.2 忽略磁盘缓存

你可以选择从内存中加载缓存,如果内存缓存不存在,则直接从网络下载,内存缓存读取数据非常快,但是当缓存达到阈值,图片缓存可能被丢弃,所以通常默认是先从内存查询,再从磁盘查询,然后从网络下载,虽然内存缓存是易失性缓存,但好在速度快,弥补了磁盘缓存IO开销大,读取速度慢的缺点,所以两者结合可以很好地实现图片缓存,建议你在自定义图片缓存框架的时候实现两者结合,而不是单独使用其中一种,另外通过改进内存缓存算法,也可以优化你的APP性能。

[self.imageView sd_setImageWithURL:[NSURL urlWithString:urlString] 
                  placeholderImage:[UIImage imageNamed:@"myPlaceHolder"]
                  options:SDWebImageRetryFailed | SDWebImageFromCacheOnly
                  completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                      if (error) {
                      }
                      else {
                          
                      }
                  }];

还有其他选择你可以根据需要进行选择,具体不在一一描述

1.5 添加一个下载进度

SDWebImage 提供了 progressblock回调,你可以配置此 block获取当前图片下载进度

[self.imageView sd_setImageWithURL:[NSURL urlWithString:urlString] 
                  placeholderImage:[UIImage imageNamed:@"myPlaceHolder"]
                  options:SDWebImageRetryFailed | SDWebImageFromCacheOnly
                  progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * targetURL){
                      
                  }
                  completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                      if (error) {
                      }
                      else {
                          
                      }
                  }];

二、高级扩展

在上面介绍的SDWebImageOptions 有一个选项做了以下描述:

/**
     * We usually don't apply transform on animated images as most transformers could not manage animated images.
     * Use this flag to transform them anyway.
     */
    SDWebImageTransformAnimatedImage = 1 << 9,

可以看到SDWebImage内部提供了对图像的Transform的能力,而最后一个接口提供了context参数,这个参数为我们提供了十分简洁的进行图片高级定制的能力。
SDWebImageContext的实现如下:

//  SDWebImageContext实际上是一个字典类型
typedef NSString * SDWebImageContextOption NS_EXTENSIBLE_STRING_ENUM;
typedef NSDictionary SDWebImageContext;

在define文件定义的后面我们可以找到如下定制类型的key:

/**
 A id instance which conforms `SDImageTransformer` protocol. It's used for image transform after the image load finished and store the transformed image to cache. If you provide one, it will ignore the `transformer` in manager and use provided one instead. (id)
 */
FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextImageTransformer;

注释上面说明了,SDWebImage定义了id协议,通过实现此协议,你可以在图片加载完成后,对图片进行transform后缓存,本文我们将实现此协议来实现定制缓存。
协议实现如下:

@protocol SDImageTransformer 
@required
/**
 For each transformer, it must contains its cache key to used to store the image cache or query from the cache. This key will be appened after the original cache key generated by URL or from user.
 @return The cache key to appended after the original cache key. Should not be nil.
 */
@property (nonatomic, copy, readonly, nonnull) NSString *transformerKey;

/**
 Transform the image to another image.
 @param image The image to be transformed
 @param key The cache key associated to the image
 @return The transformed image, or nil if transform failed
 */
- (nullable UIImage *)transformedImageWithImage:(nonnull UIImage *)image forKey:(nonnull NSString *)key;
@end

transformerKey 是你定制图片的缓存key,通过此url+transformerKey,你可以找到实现此定制的缓存图片

SDWebImage也提供了几种简单的处理方案:

2.1 Pipeline

顾名思义,你可以使用多种处理叠加生成最终处理图像进行缓存

#pragma mark - Pipeline
/**
 Pipeline transformer. Which you can bind multiple transformers together to let the image to be transformed one by one in order and generate the final image.
 @note Because transformers are lightweight, if you want to append or arrange transfomers, create another pipeline transformer instead. This class is considered as immutable.
 */
@interface SDImagePipelineTransformer : NSObject 
/**
 All transformers in pipeline
 */
@property (nonatomic, copy, readonly, nonnull) NSArray> *transformers;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithTransformers:(nonnull NSArray> *)transformers;
@end
2.2 RoundCorner

为图片添加圆角

/**
 Image round corner transformer
 */
@interface SDImageRoundCornerTransformer: NSObject 

/**
 The radius of each corner oval. Values larger than half the
 rectangle's width or height are clamped appropriately to
 half the width or height.
 */
@property (nonatomic, assign, readonly) CGFloat cornerRadius;

/**
 A bitmask value that identifies the corners that you want
 rounded. You can use this parameter to round only a subset
 of the corners of the rectangle.
 */
@property (nonatomic, assign, readonly) SDRectCorner corners;

/**
 The inset border line width. Values larger than half the rectangle's
 width or height are clamped appropriately to half the width
 or height.
 */
@property (nonatomic, assign, readonly) CGFloat borderWidth;

/**
 The border stroke color. nil means clear color.
 */
@property (nonatomic, strong, readonly, nullable) UIColor *borderColor;

- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithRadius:(CGFloat)cornerRadius corners:(SDRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(nullable UIColor *)borderColor;
@end

圆角转换支持设置边框和颜色,你也可以根据需要设置部分圆角,具体请看 SDRectCorner定义

2.3 Resizing

缩放处理,缩放是使用最为普遍的,通常情况下服务器端如果做得比较成熟的话,会提供大、中、小等图片链接,如果未做处理,并且返回的图片过大可以使用此方法处理

/**
 Image resizing transformer
 */
@interface SDImageResizingTransformer : NSObject 
/**
 The new size to be resized, values should be positive.
 */
@property (nonatomic, assign, readonly) CGSize size;
/**
 The scale mode for image content.
 */
@property (nonatomic, assign, readonly) SDImageScaleMode scaleMode;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode;
@end
2.4 Cropping

进行图片裁剪

/**
 Image cropping transformer
 */
@interface SDImageCroppingTransformer : NSObject 

/**
 Image's inner rect.
 */
@property (nonatomic, assign, readonly) CGRect rect;

- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithRect:(CGRect)rect;

@end
2.5 Flipping

图片翻转

/**
 Image flipping transformer
 */
@interface SDImageFlippingTransformer : NSObject 
/**
 YES to flip the image horizontally. ⇋
 */
@property (nonatomic, assign, readonly) BOOL horizontal;
/**
 YES to flip the image vertically. ⥯
 */
@property (nonatomic, assign, readonly) BOOL vertical;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical;
@end
2.5 Rotation

旋转图片

/**
 Image rotation transformer
 */
@interface SDImageRotationTransformer : NSObject 
/**
 Rotated radians in counterclockwise.⟲
 */
@property (nonatomic, assign, readonly) CGFloat angle;
/**
 YES: new image's size is extend to fit all content.
 NO: image's size will not change, content may be clipped.
 */
@property (nonatomic, assign, readonly) BOOL fitSize;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize;
@end
2.6 Image Blending

SDWebImage同样提供了图片颜色转换和滤镜等操作

/**
 Image tint color transformer
 */
@interface SDImageTintTransformer : NSObject 
/**
 The tint color.
 */
@property (nonatomic, strong, readonly, nonnull) UIColor *tintColor;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithColor:(nonnull UIColor *)tintColor;
@end


/**
 Image blur effect transformer
 */
@interface SDImageBlurTransformer : NSObject 
/**
 The radius of the blur in points, 0 means no blur effect.
 */
@property (nonatomic, assign, readonly) CGFloat blurRadius;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithRadius:(CGFloat)blurRadius;
@end

#if SD_UIKIT || SD_MAC
/**
 Core Image filter transformer
 */
@interface SDImageFilterTransformer: NSObject 
/**
 The CIFilter to be applied to the image.
 */
@property (nonatomic, strong, readonly, nonnull) CIFilter *filter;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithFilter:(nonnull CIFilter *)filter;
@end

三、缩放定制

因为我们的APP只要求对图片进行缩放处理,所以这里我们结合APP依赖框架封装一套能够进行图片缩放的缓存接口
实现协议:

@interface SSImageResizingTransformer : NSObject 
+ (instancetype)transformerWithSize:(CGSize)size scaleMode:(QMUIImageResizingMode)scaleMode;
@end


@interface SSImageResizingTransformer ()
@property (nonatomic, assign) CGSize size;
@property (nonatomic, assign) SDImageScaleMode scaleMode;
@end

@implementation SSImageResizingTransformer

+ (instancetype)transformerWithSize:(CGSize)size scaleMode:(QMUIImageResizingMode)scaleMode {
    SSImageResizingTransformer *transformer = [SSImageResizingTransformer new];
    transformer.size = size;
    transformer.scaleMode = scaleMode;
    return transformer;
}

- (NSString *)transformerKey {
    CGSize size = self.size;
    return [NSString stringWithFormat:@"SSImageResizingTransformer({%f,%f},%lu)", size.width, size.height, (unsigned long)self.scaleMode];
}

- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {
    if (!image) {
        return nil;
    }
    if (self.size.width <= 0 || self.size.height <= 0) {
        return image;
    }
    if (image.size.width < self.size.width && image.size.height < self.size.height){
        return image;
    }
    UIImage *scaledImage = [image qmui_imageResizedInLimitedSize:self.size resizingMode:QMUIImageResizingModeScaleAspectFit scale:UIScreen.mainScreen.scale];
    return scaledImage;
}

本文结合QMUI框架图片缩放接口对图片实现上述缩放,当图片小于缩放尺寸,或者缩放尺寸不合格则直接使用原始图片

四、接口封装

4.1 静态容器

使用静态容器存储申请的图片处理Transformer对象,避免重复申请

static NSMutableDictionary *SSImageContextContainer() {
    static NSMutableDictionary *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[NSMutableDictionary alloc]init];
    });
    return instance;
}

4.2 TransformerKey

NSString *SSTransformerKey(CGSize size, NSInteger scaleMode) {
    size.width = ceilf(size.width);
    size.height = ceilf(size.height);
    return [NSString stringWithFormat:@"SSImageResizingTransformer({%f,%f},%lu)", size.width, size.height, (unsigned long)scaleMode];
}

4.2 SDWebImageContext·

SDWebImageContext *SSGetWebImageContext(CGSize size, NSInteger scaleMode) {
    NSString *optionKey = SSTransformerKey(size,scaleMode);
    SDWebImageContext *context = HETSafeDictionaryInDict(SSImageContextContainer(),optionKey);
    if (context) {
        return context;
    }
    SSImageResizingTransformer *transformer = [SSImageResizingTransformer transformerWithSize:size scaleMode:scaleMode];
    if (transformer) {
        SDWebImageContext *imageContext = [SDWebImageContext dictionaryWithObject:transformer forKey:SDWebImageContextImageTransformer];
        [SSImageContextContainer() setValue:imageContext forKey:optionKey];
        return imageContext;
    }
    return nil;
}

4.4 实现UIImageView分类

当设置了size参数,第一次加载图片内部将会调用SSImageResizingTransformer对象对图片进行缩放,后续直接根据TransformerKey查询缓存,未设置size参数则缓存原始图片

@implementation UIImageView (SSWebImage)

- (void)SSSetImageWithURL:(nullable NSURL *)url {
    [self SSSetImageWithURL:url  placeHolderColor:nil];
}

- (void)SSSetImageWithURL:(nullable NSURL *)url
                     size:(CGSize)size
                     mode:(QMUIImageResizingMode)resizingMode {
    [self SSSetImageWithURL:url size:size mode:resizingMode  placeHolderColor:nil];
}

- (void)SSSetImageWithURL:(nullable NSURL *)url
                completed:(nullable SDExternalCompletionBlock)completedBlock{
    [self SSSetImageWithURL:url  placeHolderColor:nil completed:completedBlock];
}

- (void)SSSetImageWithURL:(nullable NSURL *)url
                     size:(CGSize)size
                     mode:(QMUIImageResizingMode)resizingMode
                completed:(nullable SDExternalCompletionBlock)completedBlock {
    [self SSSetImageWithURL:url  placeHolderColor:nil completed:completedBlock];
}


- (void)SSSetImageWithURL:(nullable NSURL *)url
         placeHolderColor:(nullable UIColor*)color {
    [self SSSetImageWithURL:url  placeHolderColor:color completed:nil];
}

- (void)SSSetImageWithURL:(nullable NSURL *)url
                     size:(CGSize)size
                     mode:(QMUIImageResizingMode)resizingMode
         placeHolderColor:(nullable UIColor*)color {
    [self SSSetImageWithURL:url size:size mode:resizingMode  placeHolderColor:color completed:nil];
}

- (void)SSSetImageWithURL:(nullable NSURL *)url
         placeHolderColor:(nullable UIColor*)color
                completed:(nullable SDExternalCompletionBlock)completedBlock {
    
    [self SSSetImageWithURL:url size:CGSizeZero mode:0  placeHolderColor:color completed:completedBlock];
}

- (void)SSSetImageWithURL:(nullable NSURL *)url
                     size:(CGSize)size
                     mode:(QMUIImageResizingMode)resizingMode
         placeHolderColor:(nullable UIColor*)color
                completed:(nullable SDExternalCompletionBlock)completedBlock {
    
    color  = color ? color : [UIColor qmui_colorWithHexString:@"#F5F5F5"];
    UIImage *placeHolderImage = [UIImage qmui_imageWithColor:color size:CGSizeMake(3, 3) cornerRadius:0];
    placeHolderImage = [placeHolderImage resizableImageWithCapInsets:UIEdgeInsetsMake(1, 1, 1, 1)];
    [self SSSetImageWithURL:url size:size mode:resizingMode placeholderImage:placeHolderImage completed:completedBlock];
}

- (void)SSSetImageWithURL:(nullable NSURL *)url
         placeholderImage:(nullable UIImage *)placeholder {
    [self SSSetImageWithURL:url placeholderImage:placeholder completed:nil];
}



- (void)SSSetImageWithURL:(nullable NSURL *)url
         placeholderImage:(nullable UIImage *)placeholder
                completed:(nullable SDExternalCompletionBlock)completedBlock{
    [self SSSetImageWithURL:url size:CGSizeZero mode:0 placeholderImage:placeholder completed:completedBlock];
}

- (void)SSSetImageWithURL:(nullable NSURL *)url
                     size:(CGSize)size
                     mode:(QMUIImageResizingMode)resizingMode
         placeholderImage:(nullable UIImage *)placeholder  {
    [self SSSetImageWithURL:url size:size mode:resizingMode placeholderImage:placeholder completed:nil];
}


- (void)SSSetImageWithURL:(nullable NSURL *)url
                     size:(CGSize)size
                     mode:(QMUIImageResizingMode)resizingMode
         placeholderImage:(nullable UIImage *)placeholder
                completed:(nullable SDExternalCompletionBlock)completedBlock{
    [self SSSetImageWithURL:url size:size mode:resizingMode placeholderImage:placeholder  options:(SDWebImageRetryFailed | SDWebImageAllowInvalidSSLCertificates)  completed:completedBlock];
}

- (void)SSSetImageWithURL:(nullable NSURL *)url
                     size:(CGSize)size
                     mode:(QMUIImageResizingMode)resizingMode
         placeholderImage:(nullable UIImage *)placeholder
                  options:(SDWebImageOptions)options
                completed:(nullable SDExternalCompletionBlock)completedBlock{
    [self SSSetImageWithURL:url size:size mode:resizingMode placeholderImage:placeholder  options:options  progress:nil completed:completedBlock];
    
}

- (void)SSSetImageWithURL:(nullable NSURL *)url
                     size:(CGSize)size
                     mode:(QMUIImageResizingMode)resizingMode
         placeholderImage:(nullable UIImage *)placeholder
                  options:(SDWebImageOptions)options
                 progress:(nullable SDImageLoaderProgressBlock)progressBlock
                completed:(nullable SDExternalCompletionBlock)completedBlock{
    SDWebImageContext *imageContext = nil;
    if (!CGSizeEqualToSize(size, CGSizeZero)) {
        imageContext = SSGetWebImageContext(size, resizingMode);
    }
    [self sd_setImageWithURL:url placeholderImage:placeholder options:options context:imageContext progress:nil completed:completedBlock];
}

六、小节

本文我们只是基于SDWebImage框架做了图片缩放缓存处理,你可以根据需要实现SDImageTransformer协议对图片进行你自己的业务处理,具体不在讲述。

目前有个疑问就是定制处理会不会导致图片重复从网络加载,如果服务器提供的图片较大,而我们需要两个规格的缩放处理,首次加载后不知道SDWebImage是不是同时也做了大图缓存,使用另外一种规格再次访问时直接提取大图缓存定制小图,还是从网络下载后再进行小图定制,后面再去阅读下源代码。

你可能感兴趣的:(【iOS】 使用SDWebImage 定制你的缓存图片)