SDWebImage 支持异步的图片下载+缓存,提供了 UIImageView+WebCacha 的 category,方便使用。使用SDWebImage首先了解它加载图片的流程。
  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. connection:didReceiveData: 中利用 ImageIO 做了按图片下载进度加载效果。
  12. connectionDidFinishLoading: 数据下载完成后交给 SDWebImageDecoder 做图片解码处理。
  13. 图片解码处理在一个 NSOperationQueue 完成,不会拖慢主线程 UI。如果有需要对下载的图片进行二次处理,最好也在这里完成,效率会好很多。
  14. 在主线程 notifyDelegateOnMainThreadWithInfo: 宣告解码完成,imageDecoder:didFinishDecodingImage:userInfo: 回调给 SDWebImageDownloader。
  15. imageDownloader:didFinishWithImage: 回调给 SDWebImageManager 告知图片下载完成。
  16. 通知所有的 downloadDelegates 下载完成,回调给需要的地方展示图片。
  17. 将图片保存到 SDImageCache 中,内存缓存和硬盘缓存同时保存。写文件到硬盘也在以单独 NSInvocationOperation 完成,避免拖慢主线程。
  18. SDImageCache 在初始化的时候会注册一些消息通知,在内存警告或退到后台的时候清理内存图片缓存,应用结束的时候清理过期图片。
  19. SDWI 也提供了 UIButton+WebCache 和 MKAnnotationView+WebCache,方便使用。
  20. SDWebImagePrefetcher 可以预先下载图片,方便后续使用
SDWebImage的案例1:在tableView中使用SDWebImage
#import <SDWebImage/UIImageView+WebCache.h>...- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{static NSString *MyIdentifier = @"MyIdentifier";UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];if (cell == nil){cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:MyIdentifier] autorelease];}// Here we use the new provided sd_setImageWithURL: method to load the web image[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]placeholderImage:[UIImage imageNamed:@"placeholder.png"]];cell.textLabel.text = @"My Text";return cell;
}

The SDWebImageManager is the class behind the UIImageView+WebCache category. It ties the asynchronous downloader with the image cache store. You can use this class directly to benefit from web image downloading with caching in another context than a UIView (ie: with Cocoa).

 NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/userManager/0.png"];//SDWebImageManager管理器继承与UIImageView+WedCache。已异步的方式进行下载图片到缓冲区。SDWebImageManager *manager = [SDWebImageManager sharedManager];[manager downloadImageWithURL:url options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {NSLog(@"%ld,%ld",receivedSize,expectedSize);}completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {//为imageView设置图片为下载的图片[self.imageView setImage:image];//打印图片的来源NSLog(@"%@",imageURL);}];

It's also possible to use the async image downloader independently:

[SDWebImageDownloader.sharedDownloader downloadImageWithURL:imageURLoptions:0progress:^(NSInteger receivedSize, NSInteger expectedSize){// progression tracking code}completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished){if (image && finished){// do something with image}}];

在自己的案例中使用SDWebImage代码段:

添加自定义的只读缓存路径,其中这是可选的,如果没有指定,系统会默认
#import "SDWebImage/SDImageCache.h"
#import "AppDelegate.h"
......
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//添加自定义的只读缓存路径:可选的NSString *bundledPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"CustomPathImages"];[[SDImageCache sharedImageCache] addReadOnlyCachePath:bundledPath];......
}

在使用缓存时,如果内存不够使用时,需要进行清理以释放内存。

#import "MasterViewController.h"
#import "SDWebImage/UIImageView+WebCache.h"
......
//清理缓存,
- (void)flushCache
{/***  1、SDImageCache是怎么做数据管理的?SDImageCache分两个部分,一个是内存层面的,一个是硬盘层面的。内存层面的相当是个缓存器,以Key-Value的形式存储图片。*///清理内存缓存[SDWebImageManager.sharedManager.imageCache clearMemory];//清理硬盘缓存[SDWebImageManager.sharedManager.imageCache clearDisk];
}
//支持屏幕旋转
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}......

//为了显示大图片,替将连接中small替换成source;

NSString *largeImageURL = [[_objects objectAtIndex:indexPath.row] stringByReplacingOccurrencesOfString:@"small" withString:@"source"];

......

 

仪表器的使用方法。

#import "DetailViewController.h"
#import "SDWebImage/UIImageView+WebCache.h"
......
- (void)configureView
{if (self.imageURL) {//创建仪表器__block UIActivityIndicatorView *activityIndicator;//为防止循环引用问题,所以在block中使用imageView时要设置成弱引用,imageView中使用block,在block中如果再调用imageView时,不设置为弱引用,会出现循环引用问题。__weak UIImageView *weakImageView = self.imageView;[self.imageView sd_setImageWithURL:self.imageURLplaceholderImage:niloptions:SDWebImageProgressiveDownloadprogress:^(NSInteger receivedSize, NSInteger expectedSize) {//检测是否已经存在啦!,如果没有在新创建出一个if (!activityIndicator) {//将新创建的仪表器添加到imageView视图中[weakImageView addSubview:activityIndicator = [UIActivityIndicatorView.alloc initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]];activityIndicator.center = weakImageView.center;//开启动画,转吧!小宇宙[activityIndicator startAnimating];}}completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL){//将仪表器从imageView视图中进行删除[activityIndicator removeFromSuperview];activityIndicator = nil;}];}
}
......

在Cell中使用异步图片下载。

#import "MasterViewController.h"
#import "SDWebImage/UIImageView+WebCache.h"
......
/***  参数解析:1.获取图片的路径2.设置占位图片3.options选项:当indexPath.row为0时,执行 SDWebImageRefreshCached:刷新缓存*/[cell.imageView sd_setImageWithURL:[NSURL URLWithString:[_objects objectAtIndex:indexPath.row]]placeholderImage:[UIImage imageNamed:@"placeholder"] options:indexPath.row == 0 ? SDWebImageRefreshCached : 0];
......

在上段代码中,有如下两行代码:

__weak UIImageView *weakImageView = self.imageView;

__block UIActivityIndicatorView *activityIndicator;

其中第一条为了避免循环引用问题,加上了__weak,第二条使用了block。现在补充一下循环引用、block的知识点:

循环引用
  所有的引用计数系统,都存在循环应用的问题。例如下面的引用关系:
     1)对象a创建并引用到了对象b.
     2)对象b创建并引用到了对象c.
     3)对象c创建并引用到了对象b.
  这时候b和c的引用计数分别是2和1。当a不再使用b,调用release释放对b的所有权,因为c还引用了b,所以b的引用计数为1,

  b不会被释放。b不释放,c的引用计数就是1,c也不会被释放。从此,b和c永远留在内存中。这种情况,必须打断循环引用

  通过其他规则来维护引用关系。比如,我们常见的delegate往往是assign方式的属性而不是retain方式 的属性,

  赋值不会增加引用计数,就是为了防止delegation两端产生不必要的循环引用。如果一个UITableViewController对象a

  通过retain获取了UITableView对象b的所有权,这个UITableView对象b的delegate又是a,如果这个delegate是retain方式的,

  那基本上就没有机会释放这两个对象了。自己在设计使用delegate模式时,也要注意这点。

Block

  是可以获取其他函数局部变量的匿名函数,其不但方便开发,并且可以大幅提高应用的执行效率(多核心CPU可直接处理Block指令),如果希望进行修改局部变量的值,可以在定义局部变量之前使用__block。

iOS_SDWebImage框架分析相关推荐

  1. Flutter框架分析(五)-- 动画

    Flutter框架分析分析系列文章: <Flutter框架分析(一)-- 总览和Window> <Flutter框架分析(二)-- 初始化> <Flutter框架分析(三 ...

  2. hdfs文档存储服务器,一文读懂HDFS分布式存储框架分析

    一文读懂HDFS分布式存储框架分析 HDFS是一套基于区块链技术的个人的数据存储系统,利用无处不在的私人PC存储空间及便捷的网络为个人提供数据加密存储服务,将闲置的存储空间利用起来,服务于正处于爆发期 ...

  3. 需求评审五个维度框架分析及其带来的启示-3-典型需求评审

    典型情境是指软件开发的常见情境,本文选择如下来进行分析: 1. 传统瀑布模型开发下的需求评审 2. 使用IEEE Std. 1028的需求评审 3. 敏捷开发下的需求评审 传统瀑布模型下的需求评审 对 ...

  4. java连接linux服务器执行shell命令(框架分析+推荐)

    java连接linux服务器执行shell命令(框架分析+推荐) 一.分类+连接方式 程序打成jar包,在本地服务器上执行shell命令.这种使用MyRuntimeUtil工具类 java程序远程li ...

  5. Linux USB驱动框架分析 【转】

    转自:http://blog.chinaunix.net/uid-11848011-id-96188.html 初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结 ...

  6. linux音频框架分析,Alsa音频子系统Codec---al5623.c内核代码框架分析

    驱动代码位于: sound/soc/codec/alc5623.c 随便找个Linux内核都会有. 1.首先进行i2c总线驱动加载在: static int __init alc5623_modini ...

  7. Janus流媒体服务器框架分析

    Janus流媒体服务器框架分析 目录 webrtc多方通信架构 Janus流媒体服务器 1. webrtc多方通信架构 1. Mesh 方案 Mesh方案即多个终端之间两两进行连接,形成一个网状结构. ...

  8. FFmpeg过滤器框架分析

    FFmpeg过滤器框架分析 目录 主要结构体和API介绍 AVFilterGraph-对filters系统的整体管理 AVFilter-定义filter本身的能⼒ AVFilterContext-fi ...

  9. Prototype 框架分析(一)

    Prototype 框架分析(一) Class 关于javascript的面向对象设计可以参看MSDN上的文章<JavaScript使用面向对象的技术创建高级 Web 应用程序>,这样理解 ...

最新文章

  1. 页面是可以这样设计的
  2. 编程之美-程序改错方法整理
  3. 微信支付退款结果通知解密 base64_decode / md5 / AES
  4. 通过反射获得引用程序集信息
  5. 三角形 画_CAD入门基础第3节:直角三角形的圆及如何修剪
  6. 在WildFly中将Apache Camel和Spring添加为jboss模块
  7. aptitude_PHP Numbers Aptitude问题与解答
  8. android 安全 权限,[原创]Android 中的那些权限
  9. .NET开发中的Exception处理三定律[转]
  10. excel保存快捷键_这应该算是Windows电脑中最强的几组快捷键!
  11. liunx Swap 分区的作用
  12. Glide4.0 centerCrop属性和圆角 冲突
  13. 英国电信推出FTTP和G.fast新试点项目
  14. heartbeat 高可用工具
  15. 软件安全备考--PE文件
  16. Linux 串口读写
  17. 基于 AUTOSAR 的电动汽车中央控制单元 CAN 通信软件开发
  18. docker-compose up -d --build不会更新镜像;什么时候容器会变更
  19. SpringBoot+Vue实现邮箱登录注册功能
  20. 【推荐】万物兴歇——衰老与寿命的演化

热门文章

  1. 电子商务网站专题页策划的6个必杀技
  2. 周鸿祎再撕逼:公关大师为何完败?
  3. CleanMyMac X2021中文官方永久免费全新系统清理管家软件
  4. IP对讲分机还有这些你想不到的功能
  5. Vue开发实例(17)之实现用户列表
  6. JavaScript(11) - 阻止事件冒泡和默认行为,拖拽,事件监听器
  7. SPOT-4卫星数据介绍
  8. 2022年软考报名人数创近3年新高,软考成绩什么时候公布?
  9. 招标 | 近期隐私计算项目招标中标33(中国邮储银行、中国移动、南湖实验室等)
  10. 商业智能BI企业管理决策之金字塔思维