第50条:构建缓存时选用NSCache而非NSDictionary

开发中,有时需要将因特网上下载的图片保存到字典中,这样的话稍后使用就无须再次下载了,其实用NSCache类更好,它是Foundation框架专门为处理这种任务而设计的。

NSCache胜于NSDictionary之处在于:

  • 当系统资源将要耗尽时,它可以自动删除最久未使用的缓存。
  • NSCache并不会拷贝键,而是保留它,在键不支持拷贝操作的情况下,使用更方便。
  • 可以通过调整缓存中的对象总数和所有对象的“总开销”来操控缓存删减器内容的时机,但绝对不要把这俩尺度当成可靠的“硬限制”,它们进对NSCache起指导作用。
  • NSCache是线程安全的,不需要编写加锁代码的情况下,多个线程也可以同时访问NSCache。

将NSPurgeableData与NSCache搭配使用,可实现自动清除数据的功能,也就是说,当NSPurgeableData对象所占内存为系统所丢弃时,该对象自身也会从缓存中移除。

下面是缓存的用法:

#import 

// 网络数据获取器类
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

你可能感兴趣的:(第50条:构建缓存时选用NSCache而非NSDictionary)