最新的库结构如下
初次导入,如果你的 Xcode 不是最新的,可能会遇到问题,解决版本
(1) 下载了SDWebImage.framework,然后拖到了工程中,然后:
#import "UIImageView+WebCache.h"
死活import不进啊,提示"UIImageView+WebCache.h file not found"
解决方法,最新版本的SDWebImage需要import的不是上面那一句了,需要:
#import<SDWebImage/UIImageView+WebCache.h>
然后build,一切OK。
(2) 另外一个问题就是:
Symbol Not Found: _objc_storeStrong
因为在no arc项目中引用了arc 的SDWebImage,更改一下: Build Settings->Other Linker Flags 添加 -fobjc-arc
.
---------------------------------------------------------------------------
第一步,在需要的地方导入头文件
#import<SDWebImage/UIImageView+WebCache.h>
第二步,调用sd_setImageWithURL:方法缓存图片,注意,这就是新版本的新方法,旧方法是 setImageWithURL : 。下面将几个方法都介绍一下。
//1 图片缓存的基本代码,就是这么简单 [self.image1 sd_setImageWithURL:imagePath1];
//2 用block 可以在图片加载完成之后做些事情 [self.image2 sd_setImageWithURL:imagePath2 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { NSLog(@"这里可以在图片加载完成之后做些事情"); }];
//3 给一张默认图片,先使用默认图片,当图片加载完成后再替换 [self.image1 sd_setImageWithURL:imagePath1 placeholderImage:[UIImage imageNamed:@"default"]];
//4 使用默认图片,而且用block 在完成后做一些事情 [self.image1 sd_setImageWithURL:imagePath1 placeholderImage:[UIImage imageNamed:@"default"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { NSLog(@"图片加载完成后做的事情"); }];
//5 options 选择方式 [self.image1 sd_setImageWithURL:imagePath1 placeholderImage:[UIImage imageNamed:@"default"] options:SDWebImageRetryFailed];
除了带options选项的方法,其他的方法都是综合存储,也就是内存缓存和磁盘缓存结合的方式,如果你只需要内存缓存,那么在options这里选择SDWebImageCacheMemoryOnly就可以了。
当你调用 setImageWithURL: 方法的时候,他会自动去给你干这么多事,当你需要在某一具体时刻做事情的时候,你可以覆盖这些方法。比如在下载某个图片的过程中要响应一个事件,就覆盖这个方法:
//覆盖方法,指哪打哪,这个方法是下载imagePath2的时候响应 SDWebImageManager *manager = [SDWebImageManager sharedManager]; [manager downloadImageWithURL:imagePath2 options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) { NSLog(@"显示当前进度"); } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { NSLog(@"下载完成"); }];
--------------------------
如果想取出 SD 缓存在本地的图片,可以使用下面代码
NSURL *url = [NSURL URLWithString:[model.content objectForKey:@"image"]]; //请求网络地址数据的同步方法 //因为这个方法在子线程(全局队列)中执行,所以不需要考虑死线程的问题 SDWebImageManager *manager = [SDWebImageManager sharedManager]; [manager diskImageExistsForURL:url]; if ([manager diskImageExistsForURL:url]) { LOG(@"11111") self.speakImage = [[manager imageCache] imageFromDiskCacheForKey:url.absoluteString]; }else{ LOG(@"3333333") NSData *data = [NSData dataWithContentsOfURL:url]; self.speakImage = [UIImage imageWithData:data]; }
--------------------------
SDWebImage 在从 URL 获取超过 2 m 的图片时,会造成在内存小的机器上闪退,解决方法,重写一下内置的方法
如上图中的 UIImage+MultiFormat.m 中
+ (UIImage *)sd_imageWithData:(NSData *)data { UIImage *image; NSString *imageContentType = [NSData sd_contentTypeForImageData:data]; if ([imageContentType isEqualToString:@"image/gif"]) { image = [UIImage sd_animatedGIFWithData:data]; } #ifdef SD_WEBP else if ([imageContentType isEqualToString:@"image/webp"]) { image = [UIImage sd_imageWithWebPData:data]; } #endif else { image = [[UIImage alloc] initWithData:data]; UIImageOrientation orientation = [self sd_imageOrientationFromImageData:data]; if (orientation != UIImageOrientationUp) { image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:orientation]; } }
//------------------------------------------------------------
// 这里是修改的代码,根据不同屏幕尺寸对图片进行裁切,使内存中图片占用较小
//------------------------------------------------------------ float width = 0.0; switch ((int)[UIScreen mainScreen].bounds.size.width) { case 320: width = 640.0; break; case 375: width = 750.0; break; case 414: width = 1242.0; break; default: width = 640.0; break; } //对网络图片进行缩放 float scaleSize = width/image.size.width; if (scaleSize < 1) { UIGraphicsBeginImageContext(CGSizeMake(image.size.width * scaleSize, image.size.height * scaleSize)); [image drawInRect:CGRectMake(0, 0, image.size.width * scaleSize, image.size.height * scaleSize)]; UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return scaledImage; } return image; }
-----------------------------------------------------------------------------------
SDWebImageDownloader
这个下载器改版很大,现在里面就一个方法,就是发起前往下载图片的函数:
[[SDWebImageDownloader sharedDownloader] downloadImageWithURL:imageUrl options:SDWebImageDownloaderProgressiveDownload progress:^(NSUInteger receivedSize, long long expectedSize) { NSLog(@"%u %lld",receivedSize,expectedSize); } completed:^(UIImage *aImage, NSData *data, NSError *error, BOOL finished) { //self.image = aImage; NSLog(@"成功了:%d",UIImageJPEGRepresentation(aImage, 1).length); }];
进度Block返回的信息有两个参数:1:下载进度. 2:文件大小.
我这里解释一下里面的options枚举的作用
SDWebImageDownloaderOptions
1:SDWebImageDownloaderLowPriority
这个属于默认的使用模式了,前往下载,返回进度Block信息,完成时调用completedBlock
2:SDWebImageDownloaderProgressiveDownload
这个是新版本加的功能,设置后,在返回进度Block的同时,返回completedBlock,里面的UIImage就是当前下载时的图片,可以实现将图片一点点显示出来的功能.
那么SDWebImageDownloader 在新版本的中的分工很明确,只做一件事情,那就是下载,只是下载而已,所以,下载成功以后的图片资源是不会自动缓存的.
如果要缓存,这里需要使用到
SDImageCache
SDImageCacheType 当下载请求结束时,通过这个枚举来告知图片的来源
1:SDImageCacheTypeNone 网络 2:SDImageCacheTypeDisk 设备硬盘 3:SDImageCacheTypeMemory 内存
将上面两步骤的需求合并可直接使用
SDWebImageManager
新版本的管理类的改动也相当大,而且就一个方法了,如下:
[[SDWebImageManager sharedManager] downloadWithURL:imageUrl options:SDWebImageLowPriority progress:^(NSUInteger receivedSize, longlong ,UIImageJPEGRepresentation(aImage, 1).length); }];
这样发起的下载请求,就会自动缓存图片资源了.
那么任何发起的下载请求,都会返回一个代理. 这个写法很神奇,值得深究啊.
也就是:SDWebImageOperation 将这个委托缓存一下,做什么用呢?一件事情,取消下载请求.
这边文章介绍了整个SDWebImage的运作原理, 真TMD 的复杂
http://blog.csdn.net/uxyheaven/article/details/7909373