洞察提升小程序标签管理,实现高效的金融行业数字化转型
964
2022-11-27
自定义SDWebImage图片缓冲区自清理机制
SDWebImage是一个开源的第三方库,使用AFNetworking集成的UIImageView+AFNetworking.h,它对于图片的缓存实际应用的是NSURLCache自带的cache机制。NSURLCache每次都要把缓存的raw data 再转化为UIImage。 对它稍微改变可以进行三种缓存图片清理方式: 1.超时图片缓冲区的清理机制。它本身只包含默认七天超时的图片缓存机制,这个超时时间可以修改。 2.图片缓冲区大小清理机制,它默认没有启用,这个最大缓冲区大小可以修改。 3.图片缓冲区手动清理,它默认不具备,可以增加这个功能。 注意:只有你使用了它加载过图像这个图片缓冲区清除机制才生效。应用启动后没有用它加载过图片,它就没有被实例化所以也不会自动清理。 它提供了UIImageView的一个分类,以支持从远程服务器-并缓存图片的功能 • 提供UIImageView的一个分类,以支持网络图片的加载与缓存管理 • 一个异步的图片加载器 • 一个异步的内存+磁盘图片缓存,并具有自动缓存过期处理功能 • 支持GIF图片 • 支持WebP图片 • 后台图片解压缩处理 • 确保同一个URL的图片不被-多次 • 确保虚假的URL不会被反复加载 • 确保-及缓存时,主线程不被阻塞 • 优良的性能 • 使用GCD和ARC • 支持Arm64 app事件注册使用经典的观察者模式,当观察到内存警告、程序被终止、程序进入后台这些事件时,程序将自动调用相应的方法处理。 可以看到最常用的缓存文件被清理的时机时程序进入后台,一般的应用不会不进入后台就出现内存不足了吧!绝大部分使用者都是过一段时间会把应用切换到后台或杀掉,若是让应用切换到前台你的手机电量也吃不消。一般的应用也不会在七天内-很大容量的图片。当然当你的手机已经产生了内存告警也能产生缓存图片清除。所以它的这种清除缓存图片的时机足够满足你的缓存图片处理。 注意:它默认只支持超过7天的图片清除。不对图片缓存大小进行控制。当然它已经做了这种机制,只是maxCacheSize为默认值0,所以不生效。 当然若你的应用-的都是不压缩的大文件,如医学图像文件。那么你就要对图片缓冲区进行控制了,你可以修改下这个库。若你的应用有可能出现在亮屏幕的情况下就-大量图片,并且图片整体很大,那么你也可以增加你清除图片的时机,主动调用图片缓存清理。当然你觉得7天时间太长需要修改超时时间,那么你也可以修改下这个库。最好的修改方法是对SDImageCache生成一个子类,来设置缓冲区的大小,清空图片缓冲区,当然你要把该类的对象存起来了,比直接修改这个库稍微麻烦下。 若你想直接修改第三方库来实现对缓冲区图片文件总大小控制或过期时间修改,只需要修改SDImageCache.m文件的3行代码就可以。若你想主动清理图片缓冲区,稍微修改下这个第三方库就可以。代码注释已经明确说明了:
如想在指定的地方主动清理缓存,打开以上通知相关代码。加入一行代码就可以了。注意,若是只有你使用过该库-过图片,那么由于这个库才有对应监听者,才能清理图片缓冲区,否则你发出的清理图片缓冲区无效。
[[NSNotificationCenter defaultCenter] postNotificationName:@"UserClenDiskNotification";
下面是它的清除图片缓冲的核心代码,不需要修改,你了解一下就可以了。
- (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock { dispatch_async(self.ioQueue, ^{ NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES]; NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey]; // 使用目录枚举器获取缓存文件的三个重要属性:(1)URL是否为目录;(2)内容最后更新日期;(3)文件总的分配大小。 NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL includingPropertiesForKeys:resourceKeys options:NSDirectoryEnumerationSkipsHiddenFiles errorHandler:NULL]; // 计算过期日期,默认为一星期前的缓存文件认为是过期的。 NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-self.maxCacheAge]; NSMutableDictionary *cacheFiles = [NSMutableDictionary dictionary]; NSUInteger currentCacheSize = 0; // 枚举缓存目录的所有文件,此循环有两个目的: // // 1. 清除超过过期日期的文件。 // 2. 为以大小为基础的第二轮清除保存文件属性。 NSMutableArray *urlsToDelete = [[NSMutableArray alloc] init]; for (NSURL *fileURL in fileEnumerator) { NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL]; // 跳过目录. if ([resourceValues[NSURLIsDirectoryKey] boolValue]) { continue; } // 记录超过过期日期的文件; NSDate *modificationDate = resourceValues[NSURLContentModificationDateKey]; if ([[modificationDate laterDate:expirationDate] isEqualToDate:expirationDate]) { [urlsToDelete addObject:fileURL]; continue; } // 保存保留下来的文件的引用并计算文件总的大小。 NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey]; currentCacheSize += [totalAllocatedSize unsignedIntegerValue]; [cacheFiles setObject:resourceValues forKey:fileURL]; } //清除记录的过期缓存文件 for (NSURL *fileURL in urlsToDelete) { [_fileManager removeItemAtURL:fileURL error:nil]; } // 如果我们保留下来的磁盘缓存文件仍然超过了配置的最大大小,那么进行第二轮以大小为基础的清除。我们首先删除最老的文件。前提是我们设置了最大缓存 if (self.maxCacheSize > 0 && currentCacheSize > self.maxCacheSize) { // 此轮清除的目标是最大缓存的一半。 const NSUInteger desiredCacheSize = self.maxCacheSize / 2; // 用它们最后更新时间排序保留下来的缓存文件(最老的最先被清除)。 NSArray *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent usingComparator:^NSComparisonResult(id obj1, id obj2) { return [obj1[NSURLContentModificationDateKey] compare:obj2[NSURLContentModificationDateKey]]; }]; // 删除文件,直到我们达到期望的总的缓存大小。 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(); }); } });}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~