构建缓存时选用NSCache而非NSDictionary

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];
        }];
    }
}

只有那种“重新计算起来很费事”的数据,才值得放入缓存中。

猜你喜欢

转载自blog.csdn.net/run_in_road/article/details/113174809