iOS学习笔记-127.SDWebImage3——缓存的清除和操作的取消
SDWebImage3——缓存的清除和操作的取消
一、清除缓存和操作最方便放在那里
当我们的app需要在多个控制器上显示图片的时候,如果发生内存警告,我们想自己来清除缓存。那么我应该放在什么地方呢?
可以放在控制器中,不过多个控制器都用来了,需要每个地方都来写,感觉有点淡淡的忧伤
放到 AppDelegate 中,这样我们只需要写一次就行啦。
二、缓存清除方法
清除缓存的方法,我们可以通过 SDWebImageManager 的单例中的 imageCache对象的方法来调用。如
[[SDWebImageManager sharedManager].imageCache clearMemory];
2.1 clearMemory清除内存
清除内存缓存,我们可以使用如下的方法
[[SDWebImageManager sharedManager].imageCache clearMemory];
那么它到底干了一些什么事情呢,我们去看看
这个方法在 SDImageCache中,如下
//清除内存缓存 - (void)clearMemory { //把所有的内存缓存都删除 [self.memCache removeAllObjects]; }
简单粗暴,删除所有内存缓存
2.2 clearDisk清除磁盘
清除内存缓存,我们可以使用如下的方法
[[SDWebImageManager sharedManager].imageCache clearMemory];
那么它到底干了一些什么事情呢,我们去看看
这个方法在 SDImageCache中,如下
//清除磁盘缓存 - (void)clearDisk { [self clearDiskOnCompletion:nil]; } //清除磁盘缓存(简单粗暴) - (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion { //开子线程异步处理 清理磁盘缓存的操作 dispatch_async(self.ioQueue, ^{ //删除缓存路径 [_fileManager removeItemAtPath:self.diskCachePath error:nil]; //重新创建缓存路径 [_fileManager createDirectoryAtPath:self.diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL]; if (completion) { //在主线程中处理completion回调 dispatch_async(dispatch_get_main_queue(), ^{ completion(); }); } }); }
同样这个清除磁盘的方式也是一样,直接删除缓存文件夹,然后在创建一个空的文件夹,完成这些操作以后,去主线中处理 completion回调。
2.2 cleanDisk清除磁盘
这个方法清除磁盘,主要从两个方面出发,
第一、文件过期那么清除,
第二、计算当前缓存的大小,和设置的最大缓存数量比较,如果超出那么会继续删除(按照文件了创建的先后顺序)
这个方法在 SDImageCache中,如下
//清除过期的磁盘缓存 - (void)cleanDisk { [self cleanDiskWithCompletionBlock:nil]; } //清除过期的磁盘缓存 - (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock { dispatch_async(self.ioQueue, ^{ NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES]; NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey]; // This enumerator prefetches useful properties for our cache files. NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL includingPropertiesForKeys:resourceKeys options:NSDirectoryEnumerationSkipsHiddenFiles errorHandler:NULL]; // 计算过期日期 NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-self.maxCacheAge]; NSMutableDictionary *cacheFiles = [NSMutableDictionary dictionary]; NSUInteger currentCacheSize = 0; // Enumerate all of the files in the cache directory. This loop has two purposes: // // 1. Removing files that are older than the expiration date. // 2. Storing file attributes for the size-based cleanup pass. // 遍历缓存路径中的所有文件,此循环要实现两个目的 // 1. 删除早于过期日期的文件 // 2. 保存文件属性以计算磁盘缓存占用空间 NSMutableArray *urlsToDelete = [[NSMutableArray alloc] init]; for (NSURL *fileURL in fileEnumerator) { NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL]; // Skip directories. // 跳过目录 if ([resourceValues[NSURLIsDirectoryKey] boolValue]) { continue; } // Remove files that are older than the expiration date; // 记录要删除的过期文件 NSDate *modificationDate = resourceValues[NSURLContentModificationDateKey]; if ([[modificationDate laterDate:expirationDate] isEqualToDate:expirationDate]) { [urlsToDelete addObject:fileURL]; continue; } // Store a reference to this file and account for its total size. //保存文件引用,以计算总大小 NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey]; currentCacheSize += [totalAllocatedSize unsignedIntegerValue]; [cacheFiles setObject:resourceValues forKey:fileURL]; } // 删除过期的文件 for (NSURL *fileURL in urlsToDelete) { [_fileManager removeItemAtURL:fileURL error:nil]; } // If our remaining disk cache exceeds a configured maximum size, perform a second // size-based cleanup pass. We delete the oldest files first. //如果剩余磁盘缓存空间超出最大限额,再次执行清理操作,删除最早的文件 if (self.maxCacheSize > 0 && currentCacheSize > self.maxCacheSize) { // Target half of our maximum cache size for this cleanup pass. const NSUInteger desiredCacheSize = self.maxCacheSize / 2; // Sort the remaining cache files by their last modification time (oldest first). NSArray *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent usingComparator:^NSComparisonResult(id obj1, id obj2) { return [obj1[NSURLContentModificationDateKey] compare:obj2[NSURLContentModificationDateKey]]; }]; // Delete files until we fall below our desired cache size. // 循环依次删除文件,直到低于期望的缓存限额 for (NSURL *fileURL in sortedFiles) { if ([_fileManager removeItemAtURL:fileURL error:nil]) { NSDictionary *resourceValues = cacheFiles[fileURL]; NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey]; currentCacheSize -= [totalAllocatedSize unsignedIntegerValue]; if (currentCacheSize < desiredCacheSize) { break; } } } } //在主线程中处理完成回调 if (completionBlock) { dispatch_async(dispatch_get_main_queue(), ^{ completionBlock(); }); } }); }
2.4 最大缓存时间
上面我们涉及到了最大缓存时间,那么它的值是多少呢?
SDImageCache 的下面方法中定义了这个默认值
//使用指定的命名空间实例化一个新的缓存存储和目录
- (id)initWithNamespace:(NSString *)ns diskCacheDirectory:(NSString *)directory {
......
//初始化默认的最大缓存时间 == 1周
_maxCacheAge = kDefaultCacheMaxCacheAge;
......
}
我们再来看看 kDefaultCacheMaxCacheAge
//默认的最大缓存时间为1周
static const NSInteger kDefaultCacheMaxCacheAge = 60 * 60 * 24 * 7; // 1 week
所以默认最大缓存时间是一个周。
### 2.5 最大缓存大小
上面我们知道,cleanDisk 的时候,除了时间,还有缓存的大小也是判断的依据,那么我们来看看,最大的缓存大小。
/**
* The maximum size of the cache, in bytes.
*
* 缓存图像总大小,以字节为单位,默认数值为0,表示不作限制
*/
@property (assign, nonatomic) NSUInteger maxCacheSize;
三、取消操作
三、取消操作
//取消当前的所有操作 [[SDWebImageManager sharedManager] cancelAll];
四、示例代码
四、示例代码
// // AppDelegate.m // 03_UIview87_SDWebImage // // Created by 杞文明 on 17/9/7. // Copyright ? 2017年 杞文明. All rights reserved. // #import "AppDelegate.h" #import "SDWebImageManager.h" @interface AppDelegate () @end @implementation AppDelegate -(void)applicationDidReceiveMemoryWarning:(UIApplication *)application{ //1.清空缓存 //clear:直接删除缓存目录下面的文件,然后重新创建空的缓存文件 //clean:清除过期缓存,计算当前缓存的大小,和设置的最大缓存数量比较,如果超出那么会继续删除(按照文件了创建的先后顺序) //过期时间:7天 [[SDWebImageManager sharedManager].imageCache cleanDisk]; // [[SDWebImageManager sharedManager].imageCache clearMemory]; //2.取消当前的所有操作 [[SDWebImageManager sharedManager] cancelAll]; } @end
上一篇: 小刘同学的第十篇博文
下一篇: 在iOS上JSON 与 XML 的比较