iOS中SDWebImage

一、SDWebImage的基本使用

小编最早也只是会基本使用,但是后来企业导师和我说SDWebImage的东西很多,只会基本使用是不够的。那么先来看看基本使用。SDWebImage的github地址
官方文档
·Objective-C

#import <SDWebImage/SDWebImage.h>
...
[imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
             placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

Swift

import SDWebImage

imageView.sd_setImage(with: URL(string: "http://www.domain.com/path/to/image.jpg"), placeholderImage: UIImage(named: "placeholder.png"))


如果在SDWebImage5.0中除了基本图片他还引入了全新的图像支持机制(GIF)支持。
Objective-C

SDAnimatedImageView *imageView = [SDAnimatedImageView new];
SDAnimatedImage *animatedImage = [SDAnimatedImage imageNamed:@"image.gif"];
imageView.image = animatedImage;

Swift

let imageView = SDAnimatedImageView()
let animatedImage = SDAnimatedImage(named: "image.gif")
imageView.image = animatedImage

二、github上SDWebImage的高级图

为了方便大家学习,小编这边把github上的SDWebImage 的架构设计图挪过来,大家可以看看。
请添加图片描述
从上图中我们可以大概的看出,整个库分为两层,Top LevelBase Module

Top Level:当UIImageView调用加载image方法,会进入SDWebImage中的UIImageView分类,在分类中调用负责加载UIImage的核心代码块ImageManager,其主要负责调度Image Cache/Image Loader,这两者分别从缓存或者网络端加载图片,并且又进行了细分。Cache中获取图片业务,拆分到了memory/disk(内存/外存)两个分类中;Image Loader(图片加载)中又分为从网络端获取或者从系统的Photos中获取。
Base Module:获取到图片的二进制数据处理,二进制解压缩,二进制中格式字节判断出具体的图片类型。

三、部分源码解读

UIView+WebCache.m
由于分类中不能添加成员变量,所以UIView+WebCache.m中使用了runtime关联了sd_imageURL图片的url、sd_imageProgress下载进度;sd_cancelCurrentImageLoad方法取消当前下载,sd_imageIndicator设置当前加载动画,sd_internalSetImageWithURL:内部通过SDWebImageManager调用加载图片过程并返回调用进度。
sd_imageURL为例,为属性重写setter、getter方法。

- (nullable NSURL *)sd_imageURL {
   
    return objc_getAssociatedObject(self, @selector(sd_imageURL));
}

- (void)setSd_imageURL:(NSURL * _Nullable)sd_imageURL {
   
    objc_setAssociatedObject(self, @selector(sd_imageURL), sd_imageURL, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

objc_getAssociatedObjectobjc_setAssociatedObject就是我们说的关联对象。在runtime.h文件中就可以找到它们的声明:

void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);

objc_setAssociatedObject 用于给对象添加关联对象,传入 nil 则可以移除已有的关联对象;

id objc_getAssociatedObject(id object, const void *key);

objc_getAssociatedObject 用于获取关联对象;

void objc_removeAssociatedObjects(id object);

objc_removeAssociatedObjects 用于移除一个对象的所有关联对象。
根据上图可以看到UIView+WebCache中有两个核心的东西分别是Indicator指示信号和Transition过渡动画。
以及最重要的是sd_internalSetImageWithURL:方法,用来 获取图片,并展示

- (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 {
   
    if (context) {
   
        // 复制以避免可变对象
        context = [context copy];
    } else {
   
        context = [NSDictionary dictionary];
    }
    NSString *validOperationKey = context[SDWebImageContextSetImageOperationKey];
    if (!validOperationKey) {
   
        // 将操作键传递到下游,可用于跟踪操作或图像视图类
        validOperationKey = NSStringFromClass([self class]);
        SDWebImageMutableContext *mutableContext = [context mutableCopy];
        mutableContext[SDWebImageContextSetImageOperationKey] = validOperationKey;
        context = [mutableContext copy];
    }
    self.sd_latestOperationKey = validOperationKey;
    //1.判断是否有正在执行的任务
    //有正在进行的任务,那么取消下载任务
    [self sd_cancelImageLoadOperationWithKey:validOperationKey];
    self.sd_imageURL = url;
    
    SDWebImageManager *manager = context[SDWebImageContextCustomManager];
    if (!manager) {
   
        //处理接下来缓存数据和下载数据之间的逻辑
        manager = [SDWebImageManager sharedManager];
    } else {
   
        // 删除此管理器以避免保留周期(管理器->加载程序->操作->上下文->管理器)
        SDWebImageMutableContext *mutableContext = [context mutableCopy];
        mutableContext[SDWebImageContextCustomManager] = nil;
        context = [mutableContext copy];
    }
    
    BOOL shouldUseWeakCache = NO;
    if ([manager.imageCache isKindOfClass:SDImageCache.class]) {
   
        shouldUseWeakCache = ((SDImageCache *)manager.imageCache).config.shouldUseWeakMemoryCache;
    }
    //2.设置Placeholder
    //SDWebImageDelayPlaceholder
    //!(options & SDWebImageDelayPlaceholder)不需要延时加载
    if (!(options & SDWebImageDelayPlaceholder)) {
   
        if (shouldUseWeakCache) {
   
            NSString *key = [manager cacheKeyForURL:url context:context];

            //调用内存缓存以触发弱缓存同步逻辑,忽略返回值并继续正常查询
            //不幸的是,这将导致两次内存缓存查询,但速度足够快
            //将来可能会重新设计或删除弱缓存功能
            [((SDImageCache *)manager.imageCache) imageFromMemoryCacheForKey:key];
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值