SDWebImage的基本使用

本文介绍了SDWebImage框架的基本使用,包括一行代码实现网络图片加载、常用方法如`sd_setImageWithURL:`和`downloadImageWithURL:`的详细解析,以及如何播放GIF图片和处理内存警告。通过实例展示了SDWebImage如何简化图片下载和缓存的处理。

  在上一篇笔记《多线程技术的综合应用》中,我们通过一个示例来演示了一下多线程技术的使用。在下载网络图片的过程中,写了很多代码,各种判断、各种缓存和优化,写了100多行代码,非常的麻烦!其实,如果使用SDWebImage框架的话,只需要一行代码就可以搞定。下面,我们就用这个框架来改造我们的代码。

  将SDWebImage框架的核心代码文件拖入到我们的项目中,在ViewController中包含头文件"UIImageView+WebCache.h",来到- tableView: cellForRowAtIndexPath:这个方法中,修改我们之前写的代码:

// MARK:- 返回tableView中每一行cell的数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // 定义cell的可重用标识符
    static NSString *reuseIdentifier = @"apps";

    // 根据可重用标识符去缓存池中取出可重用的cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];

    // 从数组apps中取出模型数据
    ESApps *apps = self.apps[indexPath.row];

    // 根据模型中的数据给cell设置相应的数据
    cell.textLabel.text = apps.name;  // 设置应用的名称
    cell.detailTextLabel.text = apps.download;  // 设置应用的下载量

    // 使用SDWebImage框架中的方法来下载网络图片
    [cell.imageView sd_setImageWithURL:[NSURL URLWithString:apps.icon] placeholderImage:[UIImage imageNamed:@"placeholder"]];
    /**
     *  第一个参数 : 下载图片的URL地址;
     *  第二个参数 : 占位图片。
     */

    // 返回cell
    return cell;
}

  只需要用imageView调用- sd_setImageWithURL: placeholderImage:这个方法,然后再将图片的URL地址和占位图片作为参数传递过去,所有的工作都结束了。我们在上一篇笔记中所做的一切工作,- sd_setImageWithURL: placeholderImage:这个方法内部都已经帮我们实现了!可以运行程序看一下实际效果:


使用SDWebImage改造我们的代码.gif

  程序运行的效果跟我们之前是一样的,但是,需要我们自己动手写的代码少了很多。由此可见,SDWebImage是多么的强大!接下来,我们将学习SDWebImage这个框架中常用的一些方法。

一、SDWebImage中常用的方法

  
  1、- sd_setImageWithURL: placeholderImage: options: progress: completed:方法

  要使用上面的方法,必须先包含头件"UIImageView+WebCache.h"。这个方法和我们在上面使用的- sd_setImageWithURL: placeholderImage:非常相似,只不过多了3个额外的参数。该方法的第三个参数是一个枚举,表示图片下载的模式,通常选择默认的就可了;第四个参数是一个block块,在这个block块中又有两个参数,其中,receivedSize表示图片已经下载完成的大小,expectedSize表示图片总大小,用这两个参数可以显示图片下载的进度;第五个参数也是一个block代码块,它里面有4个参数,分别表示下载的图片、错误信息、缓存类型和下载图片的URL地址:

// MARK:- 点击屏幕执行任务
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    // 下载图片
    [self downloadImage];
}

// MARK:- 下载网络图片,并且将它设置到imageView上面
- (void)downloadImage {

    // 给定一个URL地址,下载一张网络图片
    [self.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://i5qiniu.mtime.cn/pi/2016/09/27/095732.34817739_1000X1000.jpg"] placeholderImage:nil options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {

        // 显示下载进度
        NSLog(@"已完成:%.2f", 1.0 * receivedSize / expectedSize);

    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

        /**
         *  image : 表示要下载的图片;
         *  error : 表示错误信息;
         *  cacheType : 表示缓存类型;
         *  imageURL : 表示需要下载图片的URL地址。
         */
        NSLog(@"cacheType:%ld", cacheType);

        NSLog(@"线程---%@", [NSThread currentThread]);  // 在主线程中执行

    }];
    /**
     *  第一个参数 : 下载图片的URL地址;
     *  第二个参数 : 占位图片;
     *  第三个参数 : 图片下载的模式,可以传一个默认值;
     *  第四个参数 : 图片下载的进度;
     *  第五个参数 : 图片下载完成以后需要做的事情。
     */
}

  上面的代码是直接通过self.imageView调用- sd_setImageWithURL: placeholderImage: options: progress: completed:方法,把图片下载下来并设置上去的。运行程序看一下效果:


下载网络图片.gif

  2、- downloadImageWithURL: options: progress: completed:方法

  要使用上面的方法,需要包含头文件"SDWebImageManager.h"。其中,SDWebImageManager是一个单例。在获取到这个单例以后,可以调用上面的方法来下载图片。这个方法和第一个方法类似,相比而言少了一个参数:

// MARK:- 点击屏幕执行任务
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    // 下载图片
    [self downloadImage2];
}

// MARK:- 下载一张网络图片
- (void)downloadImage2 {

    // 只是单纯的下载一张图片
    [[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:@"http://i5qiniu.mtime.cn/pi/2016/09/27/100327.73956949_1000X1000.jpg"] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {

        // 图片的下载进度
        NSLog(@"已完成:%.2f", 1.0 * receivedSize / expectedSize);

    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {

        // 图片下载完成以后,将其设置到imageView上面
        self.imageView.image = image;

        NSLog(@"线程---%@", [NSThread currentThread]);  // 在主线程中执行
    }];
    /**
     *  第一个参数 : 下载图片的URL地址;
     *  第二个参数 : 图片下载的模式,可以传一个默认值;
     *  第三个参数 : 图片下载的进度;
     *  第四个参数 : 图片下载完成以后需要做的事情。
     */
}

  - downloadImageWithURL: options: progress: completed:这个方法内部也会做内存缓存和磁盘缓存的。运行程序看一下:


使用SDWebImageManager下载图片.gif

  3、- downloadImageWithURL: options: progress: completed:方法

  有时候只需要下载图片,不用做任何缓存,可以使用SDWebImageDownloader来下载。要使用这个工具类,就需要包含头文件#import "SDWebImageDownloader.h"。SDWebImageDownloader同样是一个单例。- downloadImageWithURL: options: progress: completed:方法也有四个参数,其含义和用法和上面两个方法基本相同。不过,使用时也有不同点。先来看一下它如何使用:

// MARK:- 点击屏幕执行任务
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    // 下载图片
    [self downloadImage3];
}

// MARK:- 下载图片
- (void)downloadImage3 {

    [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:[NSURL URLWithString:@"http://i5qiniu.mtime.cn/pi/2016/09/27/100359.71284743_1000X1000.jpg"] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {

        // 图片的下载进度
        NSLog(@"已完成:%.2f", 1.0 * receivedSize / expectedSize);

    } completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {

        // 注意,这个block块是在子线程中执行的,因此不能直接在这里刷新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{

            // 回到主线程刷新UI
            self.imageView.image = image;

        }];

        NSLog(@"线程---%@", [NSThread currentThread]);  // 在子线程中执行
    }];
    /**
     *  第一个参数 : 下载图片的URL地址;
     *  第二个参数 : 图片下载的模式,可以传一个默认值;
     *  第三个参数 : 图片下载的进度;
     *  第四个参数 : 图片下载完成以后需要做的事情,注意,这个block块本身是在子线程中执行的。
     */
}

  先运行程序,看一下这个方法使用的效果如何:


通过SDWebImageDownloader来下载图片.gif

  - downloadImageWithURL: options: progress: completed:方法在使用的时候一定要特别注意,尤其是在刷新UI的操作时,因为它的第4个参数是会开子线程的

二、SDWebImage其它知识的补充

  
  1、播放GIF图片

  我们知道,在iOS开发中,是无法直接通过+ imageNamed:方法来播放GIF图的。但是,SDWebImage框架中有一个+ sd_animatedGIFNamed:方法可以播放GIF图片。下面,我们就来演示一下这个方法如何使用。

  将准备好的GIF素材拖入到项目中,在ViewController中包含"UIImage+GIF.h"头文件,然后实现下面的代码:

// MARK:- 点击屏幕执行任务
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    // 播放GIF图
    [self playGIF];
}

// MARK:- 播放GIF图片
- (void)playGIF {

    UIImage *image = [UIImage sd_animatedGIFNamed:@"1017785"];  // 播放GIF图片

    self.imageView.image = image;
}

  + sd_animatedGIFNamed:这个类方法只有一个参数,就是GIF图的名字,使用起来跟系统自带的+ imageNamed:方法一样简单方便。运行程序看一下效果:


使用+ sd_animatedGIFNamed:方法来播放GIF图片.gif

  2、内存警告处理

  当下载的图片非常多时,可能会引发内存警告。那么,对于这一点,SDWebImage是怎么处理的呢?一般是在APPDelegate中实现- applicationDidReceiveMemoryWarning:方法,拿到SDWebImageManager,然后再调用清空缓存和取消所有操作的方法就可以了:

// MARK:- 发生内存警告时,执行相应的操作
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {

    // 清空缓存
    [[SDWebImageManager sharedManager].imageCache clearDisk];  // 清空所有的磁盘缓存
    /**
     *  在SDWebImage中,- clearDisk和- cleanDisk的区别:
     *  - clearDisk : 直接删除缓存文件夹,然后重新创建;
     *  - cleanDisk : 只清除过期缓存(在清除的过程中,会计算缓存大小与设置缓存大小之间的差值)。
     *  过期时间 : kDefaultCacheMaxCacheAge = 60 * 60 * 24 * 7,也就是一个礼拜
     */

    // 取消所有的操作
    [[SDWebImageManager sharedManager] cancelAll];
}

  在SDWebImage中,清空磁盘缓存的方法,除了- clearDisk之外,还有一个- cleanDisk,那么,这两个方法之间有什么区别呢?- clearDisk是直接清空所有的缓存,而- cleanDisk方法是有选择性的清除缓存。具体的区别如下:

- clearDisk方法,它会直接删除缓存文件夹,然后再重新创建;
  
- cleanDisk方法,它只会删除过期缓存。在删除过期缓存的过程中,它会计算剩余缓存的大小,此时,如果你设置了最大缓存,而剩余缓存恰好又大于最大缓存的话,它会继续删除缓存,直到剩余缓存小于最大缓存;删除的规则是从最早创建的缓存文件开始的;另外,过期缓存设置的时间是一个礼拜。

  好了,SDWebImage相关的知识暂时先整理到这里,后面会继续学习。详细代码参见SDWebImageExercise

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值