NSCache类更好,它是Foundation框架专门为处理存储任务设计的。
比NSDictionary好的地方在于:
1、当系统资源将要耗尽时,它可以自动删减缓存。
2、NSCache还会先行删减“最久未使用的”对象。
3、NSCache并不会“拷贝”键,而是会“保留”它,用NSDictionary实现需要用到无缝衔接技术。
4、NSCache是线程安全的,意思是:在开发者自己不编写加锁代码的前提下,多线程便可以同时访问NSCache。
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@class EOCNetworkFetcher;
typedef void(^EOCNetworkFetcherCompletionHandler) (NSData *data);
@interface EOCNetworkFetcher : NSObject
-(id)initWithURL:(NSURL *)url;
-(void)startWithCompletionHandler:(EOCNetworkFetcherCompletionHandler)handler;
@end
NS_ASSUME_NONNULL_END
#import "EOCNetworkFetcher.h"
@implementation EOCNetworkFetcher
{
NSCache *_cache;
}
-(instancetype)init
{
if (self = [super init])
{
_cache = [NSCache new];
_cache.countLimit = 100;
_cache.totalCostLimit = 5 * 1024 * 1024;
}
return self;
}
-(void)downloadDataForURL:(NSURL *)url
{
NSData *cahceData = [_cache objectForKey:url];
if (cahceData)
{
[self useData:cahceData];
}
else
{
EOCNetworkFetcher *fetcher = [[EOCNetworkFetcher alloc] initWithURL:url];
[fetcher startWithCompletionHandler:^(NSData * _Nonnull data)
{
[_cache setObject:data forKey:url cost:data.length];
[self useData:data];
}];
}
}
NSCache设置的上线,仅起指导作用,不是绝对指标。
NSPurgeableData和NSCache搭配起来使用,效果很好。是NSMutableData的子类,而且实现了NSDiscardableContent协议。
当系统资源紧张时,可以把保存NSPergeableData对象的那块内存释放掉。该对象自身也会从缓存中移除。
我们把上面的例子用NSPurgeableData来改写:
-(void)downloadDataForURL:(NSURL *)url
{
NSPurgeableData *cahceData = [_cache objectForKey:url];
if (cahceData)
{
[cahceData beginContentAccess];
[self useData:cahceData];
[cahceData endContentAccess];
}
else
{
EOCNetworkFetcher *fetcher = [[EOCNetworkFetcher alloc] initWithURL:url];
[fetcher startWithCompletionHandler:^(NSData * _Nonnull data)
{
NSPurgeableData *purgeableData = [NSPurgeableData dataWithData:data];
[_cache setObject:purgeableData forKey:url cost:purgeableData.length];
[self useData:data];
[purgeableData endContentAccess];
}];
}
}
只有那种“重新计算起来很费事”的数据,才值得放入缓存中。