开发中,有时需要将因特网上下载的图片保存到字典中,这样的话稍后使用就无须再次下载了,其实用NSCache类更好,它是Foundation框架专门为处理这种任务而设计的。
NSCache胜于NSDictionary之处在于:
- 当系统资源将要耗尽时,它可以自动删除最久未使用的缓存。
- NSCache并不会拷贝键,而是保留它,在键不支持拷贝操作的情况下,使用更方便。
- 可以通过调整缓存中的对象总数和所有对象的“总开销”来操控缓存删减器内容的时机,但绝对不要把这俩尺度当成可靠的“硬限制”,它们进对NSCache起指导作用。
- NSCache是线程安全的,不需要编写加锁代码的情况下,多个线程也可以同时访问NSCache。
将NSPurgeableData与NSCache搭配使用,可实现自动清除数据的功能,也就是说,当NSPurgeableData对象所占内存为系统所丢弃时,该对象自身也会从缓存中移除。
下面是缓存的用法:
#import <Foundation/Foundation.h>
// 网络数据获取器类
typedef void(^EOCNetworkFetcherCompletionHandler)(NSData *data);
@interface EOCNetworkFetcher : NSObject
- (id)initWithURL:(NSURL*)url;
- (void)startWithCompletionHandler:(EOCNetworkFetcherCompletionHandler)handler;
@end
// 使用获取器及缓存结果的类
@interface EOCClass : NSObject
@end
@implementation EOCClass{
NSCache *_cache;
}
- (id)init{
if ((self = [super init])) {
_cache = [NSCache new];
// 设置缓存的对象数目上限为100,总开销上限为5MB
_cache.countLimit = 100;
_cache.totalCostLimit = 5 * 1024 * 1024;
}
return self;
}
- (void)downloadDataForURL:(NSURL*)url{
// NSPurgeableData为NSMutableData的子类,采用与内存管理类似的引用计数,当引用计数为0时,该对象占用的内存可以根据需要随时丢弃
NSPurgeableData *cacheData = [_cache objectForKey:url];
if (cacheData) {
// 缓存命中
// 引用计数+1
[cacheData beginContentAccess];
// 使用缓存数据
[self useData:cacheData];
// 引用计数-1
[cacheData endContentAccess];
}else{
// 缓存未命中
EOCNetworkFetcher *fetcher = [[EOCNetworkFetcher alloc] initWithURL:url];
[fetcher startWithCompletionHandler:^(NSData *data) {
// 创建NSPurgeableData对象,引用计数+1
NSPurgeableData *purgeableData = [NSPurgeableData dataWithData:data];
[_cache setObject:purgeableData forKey:url cost:purgeableData.length];
// 使用缓存数据
[self useData:cacheData];
// 引用计数-1
[purgeableData endContentAccess];
}];
}
}
@end