一、前言
第一次使用SDWebImage是在自己做《康复医生》的时候。记得那时有一个表格要显示所有的用户头像。不使用它的时候每次加载该table都会很卡顿,后来使用后发现不卡顿了。瞬间感觉这个世界好有爱。
二、安装
首先,SDWebImage的git地址是:https://github.com/rs/SDWebImage。我们可以直接到这里进行下载,然后添加到自己的项目中去。
三、使用场景(前提是已经导入了SDWebImage这个库)
1、场景一、加载图片
使用SDWebImage可以去加载远程图片,而且还会缓存图片,下次请求会看一下是否已经存在于缓存中,如果是的话直接取本地缓存,如果不是的话则重新请求。使用方法很简单,在需要使用该场景的类中导入
#import "UIImageView+WebCache.h"
然后调用:
- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
即可。
我们还可以在UIImageView+WebCache.h中看到其他的方法,和上边的方法类似,读者自行查看即可。
2、场景二、使用它做本地缓存
很多时候我们可能拍照得到的一张图片要多个地方使用,那么我们就希望可以把这张图片放到缓存里面,然后每次用这张图片的时候就去通过特定的方式取即可。SDWebImage就有这样的一个类:SDImageCache。该类完美地帮助了我们解决了这个问题。
使用的时候,我们首先要在使用的类里面做导入:
#import "SDImageCache.h"
然后就可以进行相关的操作了。让我们直接看看SDImageCache.h文件:
@property (assign, nonatomic) NSUInteger maxMemoryCost; /** * The maximum length of time to keep an image in the cache, in seconds */ @property (assign, nonatomic) NSInteger maxCacheAge; /** * The maximum size of the cache, in bytes. */ @property (assign, nonatomic) NSUInteger maxCacheSize; /** * Returns global shared cache instance * * @return SDImageCache global instance */ + (SDImageCache *)sharedImageCache; /** * Init a new cache store with a specific namespace * * @param ns The namespace to use for this cache store */ - (id)initWithNamespace:(NSString *)ns; /** * Add a read-only cache path to search for images pre-cached by SDImageCache * Useful if you want to bundle pre-loaded images with your app * * @param path The path to use for this read-only cache path */ - (void)addReadOnlyCachePath:(NSString *)path; /** * Store an image into memory and disk cache at the given key. * * @param image The image to store * @param key The unique image cache key, usually it's image absolute URL */ - (void)storeImage:(UIImage *)image forKey:(NSString *)key; /** * Store an image into memory and optionally disk cache at the given key. * * @param image The image to store * @param key The unique image cache key, usually it's image absolute URL * @param toDisk Store the image to disk cache if YES */ - (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk; /** * Store an image into memory and optionally disk cache at the given key. * * @param image The image to store * @param recalculate BOOL indicates if imageData can be used or a new data should be constructed from the UIImage * @param imageData The image data as returned by the server, this representation will be used for disk storage * instead of converting the given image object into a storable/compressed image format in order * to save quality and CPU * @param key The unique image cache key, usually it's image absolute URL * @param toDisk Store the image to disk cache if YES */ - (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk; /** * Query the disk cache asynchronously. * * @param key The unique key used to store the wanted image */ - (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock; /** * Query the memory cache synchronously. * * @param key The unique key used to store the wanted image */ - (UIImage *)imageFromMemoryCacheForKey:(NSString *)key; /** * Query the disk cache synchronously after checking the memory cache. * * @param key The unique key used to store the wanted image */ - (UIImage *)imageFromDiskCacheForKey:(NSString *)key; /** * Remove the image from memory and disk cache synchronously * * @param key The unique image cache key */ - (void)removeImageForKey:(NSString *)key; /** * Remove the image from memory and disk cache synchronously * * @param key The unique image cache key * @param completionBlock An block that should be executed after the image has been removed (optional) */ - (void)removeImageForKey:(NSString *)key withCompletition:(void (^)())completion; /** * Remove the image from memory and optionally disk cache synchronously * * @param key The unique image cache key * @param fromDisk Also remove cache entry from disk if YES */ - (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk; /** * Remove the image from memory and optionally disk cache synchronously * * @param key The unique image cache key * @param fromDisk Also remove cache entry from disk if YES * @param completionBlock An block that should be executed after the image has been removed (optional) */ - (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletition:(void (^)())completion; /** * Clear all memory cached images */ - (void)clearMemory; /** * Clear all disk cached images. Non-blocking method - returns immediately. * @param completionBlock An block that should be executed after cache expiration completes (optional) */ - (void)clearDiskOnCompletion:(void (^)())completion; /** * Clear all disk cached images * @see clearDiskOnCompletion: */ - (void)clearDisk; /** * Remove all expired cached image from disk. Non-blocking method - returns immediately. * @param completionBlock An block that should be executed after cache expiration completes (optional) */ - (void)cleanDiskWithCompletionBlock:(void (^)())completionBlock; /** * Remove all expired cached image from disk * @see cleanDiskWithCompletionBlock: */ - (void)cleanDisk; /** * Get the size used by the disk cache */ - (NSUInteger)getSize; /** * Get the number of images in the disk cache */ - (NSUInteger)getDiskCount; /** * Asynchronously calculate the disk cache's size. */ - (void)calculateSizeWithCompletionBlock:(void (^)(NSUInteger fileCount, NSUInteger totalSize))completionBlock; /** * Check if image exists in cache already */ - (BOOL)diskImageExistsWithKey:(NSString *)key; /** * Get the cache path for a certain key (needs the cache path root folder) * * @param key the key (can be obtained from url using cacheKeyForURL) * @param path the cach path root folder * * @return the cache path */ - (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path; /** * Get the default cache path for a certain key * * @param key the key (can be obtained from url using cacheKeyForURL) * * @return the default cache path */ - (NSString *)defaultCachePathForKey:(NSString *)key;
不要看着想吐就行。先看看使用吧。
存图片:
SDImageCache *imageCache = [SDImageCache sharedImageCache];
[imageCache storeImage:image forKey:@"myphoto" toDisk:YES];
取图片:
SDImageCache *imageCache = [SDImageCache sharedImageCache]; UIImage *image = [imageCache imageFromDiskCacheForKey:@"myphoto"];
这样就可以取到自己存的图片了。可以看一下SDImageCache.h这个类了,里面提供了存图片到内存和磁盘的方法,还有取图片的方法,以及判断该图片是否存在的方法。还有就是删除图片、清空磁盘缓存、得到缓存大小等方法。
场景三、做设置中的清除缓存功能
简单来说,当我们点击清除缓存按钮的时候会触发的消息如下:
- (void)clearCaches { [MBProgressHUD showMessage:@"正在清理.."]; [[SDImageCache sharedImageCache] clearMemory]; [[SDImageCache sharedImageCache] clearDisk]; [self performSelectorOnMainThread:@selector(cleanCacheSuccess) withObject:nil waitUntilDone:YES]; }
- (void)cleanCacheSuccess
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
self.cacheLab.text = @"0.00M";
return;
});
}
很简单,就是把使用SDWebImage缓存的图片都清空就可以了,这里包括了内存中的缓存图片以及磁盘上的缓存图片。
场景四、一个APP多用户缓存存储
比如一个用户下面有好多只属于个人的图片,那么如果我们想做到当切换用户再切换当前用户还可以看到原来用户的图片时,就可以用到SDImageCache的命名空间功能。其实很简单
1、简单说一下:当我们使用SDImageCache去缓存图片的时候,如果我们是这样初始化的SDImageCache:
SDImageCache *image = [SDImageCache sharedImageCache];
那么我们会在Caches(沙盒)文件夹下看到一个com.hackemist.SDWebImageCache.default文件夹,这里就是用来存储sharedImageCache初始化的缓存存储的图片。如果我们是这样初始化SDImageCache:
SDImageCache *imageCache = [[SDImageCache alloc] initWithNamespace:@"TTTTTT"];
那么我们会在Caches文件夹下看到一个com.hackemist.SDWebImageCache.TTTTT文件夹。这里就是用来存储这样初始化的缓存存储的图片。
其他看一下源码可以知道,它是根据命名空间来命名文件夹的。
这样我们就可以用用户名作为命名空间名称,这样每次取缓存都用用户名就OK了。
还有其他的使用场景,这里就不再赘述了。
四、实现原理
其实SDWebImage之所以能够实现缓存的原理关键就是在哪个key值。
比如我们在使用
- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
的时候,其实就是把url当做了一个图片的key值,然后存储对应的图片,如果下次请求的url和这次请求的url一样,那么就直接根据url(这个key)来取图片,如果url作为key的图片缓存不存在,就去请求远程服务器,然后请求过来之后再次将url和图片对应,然后存储。
五、总结
六、其他
未完待续。