源码解读

SDWebImage 源码学习笔记·前传 ☞ 升级 4.x.x

2018-11-02  本文已影响153人  RiverSea
SDWebImage 源码学习笔记·前传.png

一、前言

前段时间对项目中使用的 SDWebImage 进行了一次升级 (3.7.6 → 4.4.2),发现变化比较大,本篇就记录一下升级过程中遇到的一些坑及填坑指南。

以此为契机,决定把之前阅读源码的笔记整理一下,于是就有了本系列后边几篇:

二、升级

现在转回到本篇的主要内容,首先当然是升级了,不过最新版的 SDWebImage 里边分了几个子 pod ,默认下载不全。为了满足我们的日常使用要求,还需要加上 WebP 和 GIF 这两个子 pod:

platform :ios, '7.0'

pod 'SDWebImage', '~> 4.0'
pod 'SDWebImage/WebP'
pod 'SDWebImage/GIF'

不过,在执行 pod install 的时候,发现 pod 'SDWebImage/WebP' 卡在了 Installing libwebp (0.6.0) 的地方。

据说 WebP 的解析库是 Google 的开源库,所以需要使用 VPN。笔者使用了蓝灯 Lantern,然后发现 浏览器可以正常访问 Google 网站,可是命令行 pod install 依然会卡住,可以通过下边两条命令检测命令行是否已添加 VPN:

curl www.google.com

执行上述命令后,如果返回了网页信息,就说明 VPN 已经添加成功。

于是猛查资料,才有了下文:

  1. 下载 Lantern

  2. 安装后,打开 Lantern,页面如下,查询自己 VPN 软件 (Lantern) 的http代理:

Lantern端口号.png

可以看出 Lantern 的 http 代理运行在 52425(选中部分) 端口,不同机器上的端口号也会不同。
为什么说是 http 而不是 https 呢?将地址栏中的域名复制出来贴到任意文本编辑器,就会发现变成了 http://localhost:52425/axxx

3.在命令行输入以下指令,查看端口使用情况:

sudo lsof -i -P
查看端口使用情况.png

可以看出来基本使用的只有 2 个代理端口,52425 和 52427,结合第一步可以得出,52425 是 http 的代理端口,52427 是 https 的代理端口 😎

4.配置命令行代理端口,有两种方式:
A、给本地 git 设置 http/https 代理

// 添加 http/https 代理的指令 https://127.0.0.1:XXXX  (XXXX代表端口号)
git config --global http.proxy https://127.0.0.1:52425
git config --global https.proxy https://127.0.0.1:52427

// 取消 http/https 代理的指令
git config --global --unset http.proxy        
git config --global --unset https.proxy

// 这种方法可以 pod install 成功,不过 curl www.google.com 不成功,即打不出 Google 的网页信息。

B、设置系统全局变量 http/https 代理

切换到etc目录下     cd /etc            

以管理员身份编辑   sudo vim bashrc 

输入密码进入后,  G $ 定位到文件末尾 按下键盘字母 i 开始输入,在最下面位置粘贴下面两句

export http_proxy=127.0.0.1:52425
export https_proxy=127.0.0.1:52427 

然后退出保存  按Esc  :wq

接下来让修改文件生效  source bashrc

最后一步 验证成功:  curl www.google.com  如果收到 google 的 html 数据代表已通。

完成后 pod 内部的结构如下:

SDWebImage4.0.png

三、使用

为叙述方便,此处将图片的 URL 定义成了宏:

#define URL_Normal          [NSURL URLWithString:@"此处是 普通静态图 地址"]
#define URL_WebP_Normal     [NSURL URLWithString:@"此处是 静态 WebP 地址"]
#define URL_WebP_Dynamic    [NSURL URLWithString:@"此处是 动态 WebP 地址"]
#define URL_GIF             [NSURL URLWithString:@"此处是 GIF 地址"]

第一种方案

    // 普通静态图
    UIImageView *imgV = [[UIImageView alloc] initWithFrame:CGRectMake(125, 70, 160, 160)];
    imgV.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:imgV];
    [imgV sd_setImageWithURL:URL_Normal];

    // WebP
    UIImageView *imgVB = [[UIImageView alloc] initWithFrame:CGRectMake(125, 70+160+10, 160, 160)];
    imgVB.backgroundColor = [UIColor lightGrayColor];
    imgVB.contentMode = UIViewContentModeScaleAspectFill;
    [self.view addSubview:imgVB];
    // WebP 静态图
//    [imgVB sd_setImageWithURL:URL_WebP_Normal];
    // WebP 动态图
    [imgVB sd_setImageWithURL:URL_WebP_Dynamic];
    
    // GIF
    FLAnimatedImageView *imgView = [[FLAnimatedImageView alloc] initWithFrame:CGRectMake(125, 70+160+10+160+10, 160, 200)];
    imgView.backgroundColor = [UIColor lightGrayColor];
    imgView.contentMode = UIViewContentModeScaleAspectFill;
    [self.view addSubview:imgView];
    [imgView sd_setShowActivityIndicatorView:YES];
    [imgView sd_setImageWithURL:URL_GIF
             placeholderImage:[UIImage imageNamed:@"placeholder"]
                      options:1];

第二种方案

统一都使用 UIImageView 展示图片,不过和上边的第一种方案有以下不同:

UIImageView *gifView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 70+160+10+160+10+200+10, kScreenW-20, 200)];
    gifView.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:gifView];
    self.imgView = gifView;
    
    SDWebImageManager *mgr = [SDWebImageManager sharedManager];
    __weak typeof(self) weakSelf = self;
    [mgr loadImageWithURL:URL_GIF // URL_WebP_Dynamic // URL_WebP_Normal // URL_Normal
                  options:1
                 progress:nil
                completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL)
    {
        SDImageFormat format = [NSData sd_imageFormatForImageData:data];
        switch (format) {
            case SDImageFormatGIF:
                weakSelf.imgView.image = [UIImage sd_animatedGIFWithData:data];
                break;
            case SDImageFormatWebP:
                weakSelf.imgView.image = [UIImage sd_imageWithWebPData:data];
                break;
            case SDImageFormatPNG:
            case SDImageFormatJPEG:
                weakSelf.imgView.image = image;
                break;
            default:
                break;
        }
    }];

第三种方案

自定义 HHImageView,在它的 init 系列方法中添加了对 GIF 的解析:

[[SDWebImageCodersManager sharedInstance] addCoder:[SDWebImageGIFCoder sharedCoder]];

这种方案对最终的调用方来说,非常简洁,不需要对各种图片区别对待。

    HHImageView *customView = [[HHImageView alloc] initWithFrame:CGRectMake(125, 70, 160, 160)];
    customView.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:customView];
    [customView sd_setShowActivityIndicatorView:YES];
    // 静态图
//    [customView sd_setImageWithURL:URL_Normal];
    // WebP 动图
//    [customView sd_setImageWithURL:URL_WebP_Normal];
    // WebP 静态图
//    [customView sd_setImageWithURL:URL_WebP_Dynamic];
    // GIF
    [customView sd_setImageWithURL:URL_GIF];

本文完整示例代码见: HHSDWebImageStudy

参考

上一篇下一篇

猜你喜欢

热点阅读