iOS利用SDWebImage图片下载缓存

2024-03-21 14:59

本文主要是介绍iOS利用SDWebImage图片下载缓存,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、我们先来了解一下SDWebImage的使用:

1、导入框架,引入头文件:

#import "UIImageView+WebCache.h"

也可以直接使用CocoaPods来引入和管理

(OC 如下)

platform :ios, '7.0'

pod 'SDWebImage', '~>3.8'

(swift)并且要确保添加了use_frameworks,iOS版本为8.0+

platform :ios, '8.0'

use_frameworks!

2、图片下载并缓存方法:

 

//得到当前图片的url

- (NSURL *)sd_imageURL;

// 异步下载图片并缓存

- (void)sd_setImageWithURL:(NSURL *)url;

// 异步下载图片并缓存,没下载完之前先显示占位图片,下载完之后再替换

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;

/**

* 异步下载图片并缓存

* @param url          下载图片路径

* @param placeholder  占位图片,直到下载完成才替换

* @param options      下载图片选择方式(这个选项也就是3中要介绍的options选项)

*/

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;

/**

* 异步下载图片并缓存,但没有占位图片,完成后可以在block中做事情

* @param url          下载图片url

* @param completedBlock

SDWebImageCompletionBlock:(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)

block中可以得到下载图片,错误信息,缓存类型,下载图片地址  参数,给用户做相应操作

*/

- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock;

/**

* 异步下载图片并缓存,提供占位图片,并完成后可以在block中做事情

* @param url            下载图片url

* @param placeholder    占位图片,直到下载完成才替换

* @param completedBlock

SDWebImageCompletionBlock:UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)

block中可以得到下载图片,错误信息,缓存类型,下载图片地址  参数,给用户做相应操作

*/

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;

/**

* 异步下载图片并缓存,不仅提供占位图,还可以设置下载方式:options,完成后可以在block中做事情

* @param url          下载图片路径

* @param placeholder  占位图片,直到下载完成才替换

* @param options      下载图片选择方式

* @param completedBlock  同上

*/

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;

/**

* 异步下载图片并缓存,不仅提供占位图,还可以设置下载方式:options,同时可以监听下载进度,完成后可以在block中做事情

* @param url          下载图片路径

* @param placeholder  占位图片,直到下载完成才替换

* @param options      下载图片选择方式

* @param progress    图片下载进度

* SDWebImageDownloaderProgressBlock:NSInteger receivedSize(当前下载大小), NSInteger expectedSize(总大小)

* @param completedBlock  同上

*/

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;

/**

* 异步下载图片并缓存,不仅提供占位图,还可以设置下载方式:options,同时可以监听下载进度,还可以提供下载大小,完成后可以在block中做事情

* @param url          下载图片路径

* @param placeholder  占位图片,直到下载完成才替换

* @param options      下载图片选择方式

* @param progress

* SDWebImageDownloaderProgressBlock:NSInteger receivedSize(当前下载大小), NSInteger expectedSize(总大小)

* @param completedBlock  同上

*/

- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;,

 

3、options所有选项

//失败后重试

SDWebImageRetryFailed = 1 << 0,

//最低优先级,当正在进行UI交互时,自动暂停内部的一些下载操作

SDWebImageLowPriority = 1 << 1,

//只缓存内存

SDWebImageCacheMemoryOnly = 1 << 2,

//渐进式下载,显示的图像是逐步在下载

SDWebImageProgressiveDownload = 1 << 3,

//刷新缓存

SDWebImageRefreshCached = 1 << 4,

//后台下载

SDWebImageContinueInBackground = 1 << 5,

/**

* Handles cookies stored in NSHTTPCookieStore by setting

* NSMutableURLRequest.HTTPShouldHandleCookies = YES;

*/

SDWebImageHandleCookies = 1 << 6,

//允许使用无效的SSL证书

SDWebImageAllowInvalidSSLCertificates = 1 << 7,

//高优先级下载

SDWebImageHighPriority = 1 << 8,

//延迟占位符

SDWebImageDelayPlaceholder = 1 << 9,

//改变动画形象

SDWebImageTransformAnimatedImage = 1 << 10,

/**

* By default, image is added to the imageView after download. But in some cases, we want to

* have the hand before setting the image (apply a filter or add it with cross-fade animation for instance)

* Use this flag if you want to manually set the image in the completion when success

*/

SDWebImageAvoidAutoSetImage = 1 << 11

4、内存处理:当app接收到内存警告时,我们要释放内存(可以在AppDelegate.m 的applicationDidReceiveMemoryWarning方法中释放,也可以在控制器的didReceiveMemoryWarning方法中释放)

SDWebImageManager *manager = [SDWebImageManager sharedManager];

// 取消正在下载的操作

[manager cancelAll];

// 清除内存缓存

[manager.imageCache clearMemory];

//释放磁盘的缓存

[manager.imageCache cleanDisk];

5、使用SDWebImageManager类:可以进行一些异步加载的工作

SDWebImageManager *manager = [SDWebImageManager sharedManager];

UIImage *cachedImage = [manager imageWithURL:url]; // 将需要缓存的图片加载进来

if (cachedImage) {

// 如果Cache命中,则直接利用缓存的图片进行有关操作

} else {

// 如果Cache没有命中,则去下载指定网络位置的图片,并且给出一个委托方法

[manager downloadWithURL:url delegate:self];

}

当然你的类要实现SDWebImageManagerDelegate协议,并且要实现协议的webImageManager:didFinishWithImage:方法。

// 当下载完成后,调用回调方法,使下载的图片显示

- (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image {

}

6、独立的异步图像下载和独立的异步图像缓存

独立的异步图像下载 

可能会单独用到异步图片下载,则一定要用downloaderWithURL:delegate:来建立一个SDWebImageDownloader实例。

SDWebImageDownloader *downloader = [SDWebImageDownloader downloaderWithURL:url delegate:self];

这样SDWebImageDownloaderDelegate协议的方法imageDownloader:didFinishWithImage:被调用时下载会立即开始并完成。

独立的异步图像缓存

SDImageCache类提供一个创建空缓存的实例,并用方法imageForKey:来寻找当前缓存。

UIImage *myCachedImage = [SDImageCache sharedImageCache] imageFromKey:myCacheKey];

存储一个图像到缓存是使用方法storeImage: forKey:

[SDImageCache sharedImageCache] storeImage:myImage forKey:myCacheKey];

默认情况下,图像将被存储在内存缓存和磁盘缓存中。如果仅仅是想内存缓存中,要使用storeImage:forKey:toDisk:方法的第三个参数带一负值来替代。

来替代。

二、SDWebImage内部实现原理

      SDImageCache是怎么做数据管理的?(如下图所示:)


图片解释:内存层面的相当是个缓存器,以Key-Value的形式存储图片。当内存不够的时候会清除所有缓存图片。用搜索文件系统的方式做管理,文件替换方式是以时间为单位,剔除时间大于一周的图片文件。当SDWebImageManager向SDImageCache要资源时,先搜索内存层面的数据,如果有直接返回,没有的话去访问磁盘,将图片从磁盘读取出来,然后做Decoder,将图片对象放到内存层面做备份,再返回调用层。

1、入口 setImageWithURL:placeholderImage:options: 会先把 placeholderImage 显示,然后 SDWebImageManager 根据 URL 开始处理图片。

2、进入 SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交给 SDImageCache 从缓存查找图片是否已经下载 queryDiskCacheForKey:delegate:userInfo:.

3、如果内存中已经有图片缓存,SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager。

4、SDWebImageManagerDelegate 回调 webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展示图片。

5、如果内存缓存中没有,生成 NSInvocationOperation 添加到队列开始从硬盘查找图片是否已经缓存。

6、根据 URLKey 在硬盘缓存目录下尝试读取图片文件。这一步是在 NSOperation 进行的操作,所以回主线程进行结果回调 notifyDelegate:。

7、如果硬盘中有该图片,将图片添加到内存缓存中(如果空闲内存过小,会先清空内存缓存)。SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo:。进而回调展示图片。

8、如果从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片,需要下载图片,回调 imageCache:didNotFindImageForKey:userInfo:。

9、共享或重新生成一个下载器 SDWebImageDownloader 开始下载图片。

10、图片下载由 NSURLConnection 来做,实现相关 delegate 来判断图片下载中、下载完成和下载失败。

11、imageDownloader:didFinishWithImage: 回调给 SDWebImageManager 告知图片下载完成。

12、通知所有的 downloadDelegates 下载完成,回调给需要的地方展示图片。

13、将图片保存到 SDImageCache 中,内存缓存和硬盘缓存同时保存。写文件到硬盘也在以单独 NSInvocationOperation 完成,避免拖慢主线程。SDImageCache 在初始化的时候会注册一些消息通知,在内存警告或退到后台的时候清理内存图片缓存,应用结束的时候清理过期图片。

大体过程总结了一下就是这样的:

SD_WebImage主要SD_WebImageManager单例类来管理SD_WebImageDownloader和SD_ImageCache这两个单例类。
1.当执行下载操作的时候,SD_ImageCache会从内存图片缓存中找有没有这个图片,如果有,SD_ImageCacheDelegate就会通过一系列的回调到UIImageView+WebCache到前端展示图片,如果内存缓存没有->
2.会到硬盘缓存当中找,如果有,就会将图片添加到内存缓存中(这里注意一点,如果空闲内存过小,会先清空内存缓存)然后也是SD_ImageCacheDelegate通过一系列的回调到UIImageView+WebCache到前端展示图片;如果没有->
3.就需要用SD_WebImageDownloader开始下载图片,图片下载由NSURLConnection来做,实现相关的代理来判断图片下载中,下载完成,下载失败,当图片下载完成后会交给SD_WebImageDecoder做图片解码处理,然后也是通过一系列的回调到UIImageView+WebCache到前端展示图片。另外也会将下载好的图片保存到SD_ImageCache中。

此文大部分借鉴了简书作者此生逍遥的文章,然后个人总结的。

转载于:https://www.cnblogs.com/ansyxpf/p/5624788.html

这篇关于iOS利用SDWebImage图片下载缓存的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/832979

相关文章

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

缓存雪崩问题

缓存雪崩是缓存中大量key失效后当高并发到来时导致大量请求到数据库,瞬间耗尽数据库资源,导致数据库无法使用。 解决方案: 1、使用锁进行控制 2、对同一类型信息的key设置不同的过期时间 3、缓存预热 1. 什么是缓存雪崩 缓存雪崩是指在短时间内,大量缓存数据同时失效,导致所有请求直接涌向数据库,瞬间增加数据库的负载压力,可能导致数据库性能下降甚至崩溃。这种情况往往发生在缓存中大量 k

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序

Redis中使用布隆过滤器解决缓存穿透问题

一、缓存穿透(失效)问题 缓存穿透是指查询一个一定不存在的数据,由于缓存中没有命中,会去数据库中查询,而数据库中也没有该数据,并且每次查询都不会命中缓存,从而每次请求都直接打到了数据库上,这会给数据库带来巨大压力。 二、布隆过滤器原理 布隆过滤器(Bloom Filter)是一种空间效率很高的随机数据结构,它利用多个不同的哈希函数将一个元素映射到一个位数组中的多个位置,并将这些位置的值置

防止缓存击穿、缓存穿透和缓存雪崩

使用Redis缓存防止缓存击穿、缓存穿透和缓存雪崩 在高并发系统中,缓存击穿、缓存穿透和缓存雪崩是三种常见的缓存问题。本文将介绍如何使用Redis、分布式锁和布隆过滤器有效解决这些问题,并且会通过Java代码详细说明实现的思路和原因。 1. 背景 缓存穿透:指的是大量请求缓存中不存在且数据库中也不存在的数据,导致大量请求直接打到数据库上,形成数据库压力。 缓存击穿:指的是某个热点数据在

PHP APC缓存函数使用教程

APC,全称是Alternative PHP Cache,官方翻译叫”可选PHP缓存”。它为我们提供了缓存和优化PHP的中间代码的框架。 APC的缓存分两部分:系统缓存和用户数据缓存。(Linux APC扩展安装) 系统缓存 它是指APC把PHP文件源码的编译结果缓存起来,然后在每次调用时先对比时间标记。如果未过期,则使用缓存的中间代码运行。默认缓存 3600s(一小时)。但是这样仍会浪费大量C

缓存策略使用总结

缓存是提高系统性能的最简单方法之一。相对而言,数据库(or NoSQL数据库)的速度比较慢,而速度却又是致胜的关键。 如果使用得当,缓存可以减少相应时间、减少数据库负载以及节省成本。本文罗列了几种缓存策略,选择正确的一种会有很大的不同。缓存策略取决于数据和数据访问模式。换句话说,数据是如何写和读的。例如: 系统是写多读少的吗?(例如基于时间的日志)数据是否是只写入一次并被读取多次?(例如用户配

uniapp小程序下载缓存服务器上的图片

1. 使用uni.downloadFile,但是注意下载图片的地址里的域名,需要在微信公众平台里面的downloadFile合法域名进行配置。 export default function downloadAndCacheImage(imageUrl, name) {return new Promise((resolve, reject) => {console.log("imageUrl",

基于canal的Redis缓存双写

canal地址:alibaba/canal: 阿里巴巴 MySQL binlog 增量订阅&消费组件 (github.com)https://github.com/alibaba/canal 1. 准备 1.1 MySQL 查看主机二进制日志 show master status 查看binlog是否开启 show variables like 'log_bin' 授权

插件:清理maven错误缓存.bat

插件:https://pan.baidu.com/s/1nHIxHoo1C4MvFlW7QbZe5Q?pwd=7zenhttps://pan.baidu.com/s/1nHIxHoo1C4MvFlW7QbZe5Q?pwd=7zen没错误缓存时: 有错误缓存时: