SDWebImage的基本使用

来源:互联网 发布:网络管理需求分析 编辑:程序博客网 时间:2024/05/22 04:27

  在上一篇笔记《多线程技术的综合应用》中,我们通过一个示例来演示了一下多线程技术的使用。在下载网络图片的过程中,写了很多代码,各种判断、各种缓存和优化,写了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。