在iOS开发中,经常遇到一个问题,就是如何缓存从网上下载好的图片。首先想到的办法是将图片保存在字典中。但是使用NSCache来保存的话,会更好。
NSCache于字典的不同之处在于,当系统资源耗尽时,NSCache可以自行删除缓存,而采用字典要自己编写挂钩。此外NSCache并不会拷贝键,而是采用保留,NSCache对象不拷贝键的原因在于,键都是由不支持拷贝的操作对象来充当的。最后NSCache是线程安全的。
新建一个图片缓存的类
#import <Foundation/Foundation.h>
@class FNSImageCache;
@protocol FNSImageCacheDelegate <NSObject>
@optional
- (void)successFetchData:(NSData *)data;
@end
@interface FNSImageCache : NSObject
@property (nonatomic,weak) id<FNSImageCacheDelegate> delegate;
-(void)fetchDataWithURL:(NSURL *)url;
@end
#import "FNSImageCache.h"
@implementation FNSImageCache
{
NSCache *_cache;
}
- (instancetype)init
{
if (self = [super init]) {
_cache = [NSCache new];
_cache.countLimit = 100;
_cache.totalCostLimit = 5 * 1024 * 1024;
}
return self;
}
- (void)fetchDataWithURL:(NSURL *)url
{
NSData *cacheData = [_cache objectForKey:url];
if (cacheData) {
[self useData:cacheData];
}
else{
[self downloadDataFromInternet:url];
}
}
- (void)downloadDataFromInternet:(NSURL *)url{
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
[_cache setObject:data forKey:url cost:data.length];
[self useData:data];
}];
[task resume];
}
- (void)useData:(NSData *)data{
if ([self.delegate respondsToSelector:@selector(successFetchData:)]) {
[self.delegate successFetchData:data];
}
}
@end
控制器中
#import "ViewController.h"
#import "FNSImageCache.h"
@interface ViewController ()<FNSImageCacheDelegate>
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
- (IBAction)downloadImageClick:(id)sender;
@property (nonatomic,strong) FNSImageCache *cache;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)downloadImageClick:(id)sender {
FNSImageCache *cache = [[FNSImageCache alloc] init];
cache.delegate = self;
NSURL *url = [NSURL URLWithString:@"https://gd2.alicdn.com/bao/uploaded/i2/TB1cXuXHFXXXXaxXVXXXXXXXXXX_!!0-item_pic.jpg"];
[cache fetchDataWithURL:url];
}
//FNSImageCache的代理方法
- (void)successFetchData:(NSData *)data
{
UIImage *image = [UIImage imageWithData:data];
[self.imageView setImage:image];
}
@end