[New learn]SDWebImage框架的基本使用
代码:https://github.com/xufeng79x/SDWebImage
1.简介
SDWebImage是一个第三方框架,它能够帮助我们有效管理应用图片下载,沙盒保存和内存保存的任务。通过这篇文章将了解到它的原理和一般使用方式。
2.图片获取
记得在[New learn] 设计模式文章中我们讨论了通过LibraryAPI类将HTTPClient和PersistencyManager包装起来进行图片的下载,基本原理为:
当本地沙盒中存在对应图片文件时候load本地文件否则回去网上下载并保存在本地以备后续使用。这里我们在增加一个内存缓存,将图片缓存在内存中:
增加图片缓存:
@interface PersistencyManager () {
// an array of all albums
NSMutableArray *albums;
// 图片缓存
NSMutableDictionary *imageCache;
}
@end
随后在图片保存以及在图片从沙盒读取的时候讲image信息放入其中,等待下次再去读取相同图片的时候就直接会去缓存中读取。
- (void)saveImage:(UIImage*)image filename:(NSString*)filename
{
// 进到这里可以认为图片刚从往下下载了
NSLog(@"Get the image:%@ from internet!", filename);
// 将图片放到缓存中
[imageCache setObject:image forKey:filename];
。。。。。。
}
- (UIImage*)getImage:(NSString*)filename
{
NSString *fileName = filename;
// 先从缓存中获取数据,如果有就直接返回
UIImage *image = [imageCache objectForKey:filename];
if (image) {
NSLog(@"Get the image:%@ from cache!", filename);
return image;
}
。。。。。
// 当图片在沙盒中,但是没有在缓存中,将图片放到缓存
if (image)
{
NSLog(@"Get the image:%@ from sandbox!", fileName);
// 将图片放到缓存中
[imageCache setObject:image forKey:fileName];
}
return image;
}
测试
1.获取沙盒路径:
(lldb) po NSHomeDirectory() /Users/apple/Library/Developer/CoreSimulator/Devices/8E2826AC-C429-4A39-B0EE-C261E155E191/data/Containers/Data/Application/0251E391-F9DD-4BA3-AA81-74D35F9613B5 (lldb)
2.前往沙盒,删除沙盒中已经存在的图片:

3.运行程序,此时由于缓存和沙盒中并没有图片信息,他将从网络上下载图片。
BlueLibrary[:] Get the image:d000baa1cd11728b0d5fc2bec9fcc3cec3fd2c3f.jpg from internet! -- :::] Get the image:.jpg from internet! -- :::] Get the image:.jpg from internet! -- :::] Get the image:.jpg from internet! -- :::] Get the image:.jpg from internet!
沙盒文件夹中会生成图:

4.当点击删除按钮的时候,程序会重新load 封面图片,这个时候回从哪里读取图片呢?
-- :::] Get the image:.jpg from cache! -- :::] Get the image:d000baa1cd11728b0d5fc2bec9fcc3cec3fd2c3f.jpg from cache! -- :::] Get the image:.jpg from cache! -- :::] Get the image:.jpg from cache!
可以看到都是从缓存中将图片读取出来,这是由于网络下载图片后会在沙盒生成文件并将在缓存中保存这些图片。
5.当关闭程序,在运行应用的时候,应该会从沙盒中读取,因为缓存中由于重启的原因不会有数据。
-- :::] Get the image:.jpg from sandbox! -- :::] Get the image:d000baa1cd11728b0d5fc2bec9fcc3cec3fd2c3f.jpg from sandbox! -- :::] Get the image:.jpg from sandbox! -- :::] Get the image:.jpg from sandbox! -- :::] Get the image:.jpg from sandbox!
上述流程总结:
在这节中我们自己实现了图片的下载,保存和缓存。大致的实现原理如下:

其中在我们的应用中还不会出现多线程操作的重复问题,如果有这个场景,那么我们就需要在新建一个线程缓存区判断下载指定图片的线程是否存在,如果存在就不在进行重复操作。
3.使用框架SDWebImage
上述的过程复杂繁琐,在iOS开发世界中,我们同样可以使用很多第三方框架,SDWebImage框架就是解决我们上述场景的解决方案。
3.1 什么是SDWebImage
官网:https://github.com/rs/SDWebImage
3.2 如何使用
下载框架:进入官网,点击Download ZIP

导入框架:将框架文件夹拷贝到工程中

使用框架:
框架为我们提供丰富的API和属性参数。
直接使用框架方法来代替现有代码:
- (void)downloadImage:(NSNotification*)notification
{
UIImageView *imageView = notification.userInfo[@"imageView"];
NSString *coverUrl = notification.userInfo[@"coverUrl"];
// 框架的词方法的功能已经可以替代注释掉的代码的功能
[imageView sd_setImageWithURL:[NSURL URLWithString:coverUrl] placeholderImage:nil];
// // 2 从缓存或者沙盒中读取图片
// imageView.image = [persistencyManager getImage:[coverUrl lastPathComponent]];
//
// if (imageView.image == nil)
// {
// // 3 当缓存或者沙盒中图片不存在的时候,远程多线程下载图片。
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// UIImage *image = [httpClient downloadImage:coverUrl];
//
// // 4 图片下载完毕后需要在主线程中更行UI,并保存图片到沙盒和刷新缓存
// dispatch_sync(dispatch_get_main_queue(), ^{
// imageView.image = image;
// [persistencyManager saveImage:image filename:[coverUrl lastPathComponent]];
// });
// });
// }
}
将沙盒中的图片文件删除,重启应用。
非常不幸,和我一样遇到了如下的问题吗?
Undefined symbols for architecture x86_64:
"_CGImageSourceCopyPropertiesAtIndex", referenced from:
+[UIImage(MultiFormat) sd_imageOrientationFromImageData:] in UIImage+MultiFormat.o
-[SDWebImageDownloaderOperation connection:didReceiveData:] in SDWebImageDownloaderOperation.o
+[UIImage(GIF) sd_frameDurationAtIndex:source:] in UIImage+GIF.o
"_CGImageSourceCreateImageAtIndex", referenced from:
-[SDWebImageDownloaderOperation connection:didReceiveData:] in SDWebImageDownloaderOperation.o
+[UIImage(GIF) sd_animatedGIFWithData:] in UIImage+GIF.o
"_CGImageSourceCreateWithData", referenced from:
+[UIImage(MultiFormat) sd_imageOrientationFromImageData:] in UIImage+MultiFormat.o
-[SDWebImageDownloaderOperation connection:didReceiveData:] in SDWebImageDownloaderOperation.o
+[UIImage(GIF) sd_animatedGIFWithData:] in UIImage+GIF.o
"_CGImageSourceGetCount", referenced from:
+[UIImage(GIF) sd_animatedGIFWithData:] in UIImage+GIF.o
"_OBJC_CLASS_$_MKAnnotationView", referenced from:
l_OBJC_$_CATEGORY_MKAnnotationView_$_WebCache in MKAnnotationView+WebCache.o
l_OBJC_$_CATEGORY_MKAnnotationView_$_WebCacheDeprecated in MKAnnotationView+WebCache.o
"_kCGImagePropertyGIFDelayTime", referenced from:
+[UIImage(GIF) sd_frameDurationAtIndex:source:] in UIImage+GIF.o
"_kCGImagePropertyGIFDictionary", referenced from:
+[UIImage(GIF) sd_frameDurationAtIndex:source:] in UIImage+GIF.o
"_kCGImagePropertyGIFUnclampedDelayTime", referenced from:
+[UIImage(GIF) sd_frameDurationAtIndex:source:] in UIImage+GIF.o
"_kCGImagePropertyOrientation", referenced from:
+[UIImage(MultiFormat) sd_imageOrientationFromImageData:] in UIImage+MultiFormat.o
-[SDWebImageDownloaderOperation connection:didReceiveData:] in SDWebImageDownloaderOperation.o
"_kCGImagePropertyPixelHeight", referenced from:
-[SDWebImageDownloaderOperation connection:didReceiveData:] in SDWebImageDownloaderOperation.o
"_kCGImagePropertyPixelWidth", referenced from:
-[SDWebImageDownloaderOperation connection:didReceiveData:] in SDWebImageDownloaderOperation.o
ld: symbol(s) not found for architecture x86_64
解决方法:发生此问题的原因为框架还依赖于其他框架http://stackoverflow.com/questions/12306161/build-fail-when-using-sdwebimage
验证:

同时在沙盒中发现框架已经将图片存入了特定的文件夹中:

4. SDWebImage再研究:
在测试中我们使用到了一个API方法,通过URL来获取图片的方法内部其实都调用了以下实现方法
/** * Set the imageView `image` with an `url`, placeholder and custom options. * * The download is asynchronous and cached. * * @param url The url for the image. * @param placeholder The image to be set initially, until the image request finishes. * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. * @param progressBlock A block called while image is downloading * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean * indicating if the image was retrieved from the local cache or from the network. * The fourth parameter is the original image url. */ - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
它能够制定图片占位符号,操作选项(是否缓存图片等),下载中处理和下载后处理块。
除此之外,对于gif图片来说,和调用普通图片并没有任何差别。
原理:
其实此框架的原理和我们前面自己实现的原理是一个道理,它也有缓存,沙盒存储和网络下载三部分。我们可以通过SDImageCache.m定义的如下方法可见一斑:
#if TARGET_OS_IPHONE
// Subscribe to app events
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(clearMemory)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(cleanDisk)
name:UIApplicationWillTerminateNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(backgroundCleanDisk)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
#endif
详见:https://github.com/rs/SDWebImage
以上。
[New learn]SDWebImage框架的基本使用的更多相关文章
- iOS开发——多线程篇——快速生成沙盒目录的路径,多图片下载的原理、SDWebImage框架的简单介绍
一.快速生成沙盒目录的路径 沙盒目录的各个文件夹功能 - Documents - 需要保存由"应用程序本身"产生的文件或者数据,例如:游戏进度.涂鸦软件的绘图 - 目录中的文件会被 ...
- [New learn] UIKit 框架类
NSObject NSObject is the root class of most Objective-C class hierarchies. NSDataAsset The NSDataAss ...
- iOS边练边学--多线程练习的多图片下载 以及 使用第三方框架(SDWebImage)的多图片下载
一.自己实现多图片下载应该注意的问题 沙盒缓存的问题 程序缓存的问题 cell重复利用显示图片混乱的问题 -- 用户拖拽快,下载图片慢导致的 解决图片混乱引入NSOperation集合的问题 资源下载 ...
- AJ学IOS(55)多线程网络之图片下载框架之SDWebImage
AJ分享,必须精品 效果: 代码: - (NSArray *)apps { if (!_apps) { NSArray *dictArray = [NSArray arrayWithContentsO ...
- SDWebImage ReadMe.md文档简单说明
SDWebImage ReadMe.md 文档 附:SDWebImage框架github下载地址:https://github.com/rs/SDWebImage 注1:该文章简单翻译了SDWebIm ...
- 多线程与网络之SDWebImage和NSCache
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- 搭建简单的网络部分(OC)框架
准备工作 1.文件目录结构示图(按照MVC分层) 文件目录结构图/自定义Cell Controller: CYXOneViewController Model: CYXMenu View: CYXCe ...
- iOS利用SDWebImage实现缓存的计算与清理
概述 可以仅仅清理图片缓存, 也可以清理所有的缓存文件(包括图片.视频.音频等). 详细 代码下载:http://www.demodashi.com/demo/10717.html 一般我们项目中的缓 ...
- IOS-第三方(SDWebImage)
SDWebImage ReadMe.md 文档 附:SDWebImage框架github下载地址:https://github.com/rs/SDWebImage注1:该文章简单翻译了SDWebIma ...
随机推荐
- monitor_guiagent
monitor_guiagent monitor_guiagent.sh #!/usr/bin/env bash #filename : monitor_guiagent.sh #Usage: /us ...
- Elasticsearch 更新索引settings
1.更新索引设置:将副本减至0,修改索引分析器为ik_max_word和检索分词器为ik_smart 2.需要先将索引关闭,然后再PUT setings POST user/_close PUT us ...
- 1406: [AHOI2007]密码箱
1406: [AHOI2007]密码箱 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1591 Solved: 944[Submit][Status][ ...
- iOS图片上传后被旋转的问题
最近用PHP做了一个图片合成程序,前端是通过HTML的file input选取自定图片,POST到php后台调整尺寸后与事先准备好的背景图进行合成. 通过测试发现,上传后的自定图片有的被旋转了,有的是 ...
- mysql前缀索引优化示例
现有一数据表,数据量79W, 微信openid字段为定长28位char型,目前是做的全字段索引,需要做一下索引优化,. 我们先来看下选择性, 全字段索引的: SELECT COUNT(DISTINCT ...
- Linux实验一
一.Linux 简介 1.Linux 就是一个操作系统,就像你多少已经了解的 Windows(xp,7,8)和 Max OS , 我们的 Linux 也就是系统调用和内核那两层,当然直观的来看,我们使 ...
- POI 2018.10.27
[POI2015]LOG 维护一个长度为n的序列,一开始都是0,支持以下两种操作:1.U k a 将序列中第k个数修改为a.2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1,询问能否进 ...
- NOIP2009 codevs1173 洛谷P1073 最优贸易
Description: 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分为双向通 ...
- HDU 2852 主席树
KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- Reduce Side Join实现
关于reduce边join,其最重要的是使用MultipleInputs.addInputPath这个api对不同的表使用不同的Map,然后在每个Map里做一下该表的标识,最后到了Reduce端再根据 ...