NSOperation
NSOperationQueue
的使用
apps.plist
1-apps.plist.png
ZYXApp.h
#import <Foundation/Foundation.h>
@interface ZYXApp : NSObject
/** 圖標(biāo) */
@property (nonatomic, strong) NSString *icon;
/** 下載量 */
@property (nonatomic, strong) NSString *download;
/** 名字 */
@property (nonatomic, strong) NSString *name;
+ (instancetype)appWithDict:(NSDictionary *)dict;
@end
ZYXApp.m
#import "ZYXApp.h"
@implementation ZYXApp
+ (instancetype)appWithDict:(NSDictionary *)dict
{
ZYXApp *app = [[self alloc] init];
[app setValuesForKeysWithDictionary:dict];
return app;
}
@end
ViewController.m
#import "ViewController.h"
#import "ZYXApp.h"
@interface ViewController ()
/** 所有數(shù)據(jù) */
@property (nonatomic, strong) NSArray *apps;
/** 內(nèi)存緩存的圖片 url-image對象 */
@property (nonatomic, strong) NSMutableDictionary *images;
/** 所有的操作對象 url-NSOperation對象 */
@property (nonatomic, strong) NSMutableDictionary *operations;
/** 隊列對象 */
@property (nonatomic, strong) NSOperationQueue *queue;
@end
@implementation ViewController
- (NSOperationQueue *)queue
{
if (!_queue) {
_queue = [[NSOperationQueue alloc] init];
_queue.maxConcurrentOperationCount = 3;
}
return _queue;
}
- (NSMutableDictionary *)operations
{
if (!_operations) {
_operations = [NSMutableDictionary dictionary];
}
return _operations;
}
- (NSMutableDictionary *)images
{
if (!_images) {
_images = [NSMutableDictionary dictionary];
}
return _images;
}
- (NSArray *)apps
{
if (!_apps) {
NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"apps.plist" ofType:nil]];
NSMutableArray *appArray = [NSMutableArray array];
for (NSDictionary *dict in dictArray) {
[appArray addObject:[ZYXApp appWithDict:dict]];
}
_apps = appArray;
}
return _apps;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
self.images = nil;
self.operations = nil;
[self.queue cancelAllOperations];
}
#pragma mark - 數(shù)據(jù)源方法
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.apps.count;
}
核心方法:
/**
* 核心方法
*/
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *ID = @"app";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
ZYXApp *app = self.apps[indexPath.row];
cell.textLabel.text = app.name;
cell.detailTextLabel.text = app.download;
// 先從內(nèi)存緩存中取出圖片
UIImage *image = self.images[app.icon];
if (image) { // 內(nèi)存中有圖片
cell.imageView.image = image;
} else { // 內(nèi)存中沒有圖片
// 獲得Library/Caches文件夾
NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
// 獲得文件名
NSString *filename = [app.icon lastPathComponent];
// 計算出文件的全路徑
NSString *file = [cachesPath stringByAppendingPathComponent:filename];
// 加載沙盒的文件數(shù)據(jù)
NSData *data = [NSData dataWithContentsOfFile:file];
if (data) { // 直接利用沙盒中圖片
UIImage *image = [UIImage imageWithData:data];
cell.imageView.image = image;
// 存到字典中
self.images[app.icon] = image;
} else { // 下載圖片
cell.imageView.image = [UIImage imageNamed:@"placeholder"];
NSOperation *operation = self.operations[app.icon];
if (operation == nil) { // 這張圖片暫時沒有下載任務(wù)
operation = [NSBlockOperation blockOperationWithBlock:^{
// 下載圖片
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]];
// 數(shù)據(jù)加載失敗
if (data == nil) {
// 移除操作
[self.operations removeObjectForKey:app.icon];
return;
}
UIImage *image = [UIImage imageWithData:data];
// 存到字典中
self.images[app.icon] = image;
// 回到主線程顯示圖片
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}];
// 將圖片文件數(shù)據(jù)寫入沙盒中
[data writeToFile:file atomically:YES];
// 移除操作
[self.operations removeObjectForKey:app.icon];
}];
// 添加到隊列中
[self.queue addOperation:operation];
// 存放到字典中
self.operations[app.icon] = operation;
}
}
}
return cell;
}
@end
下載的圖片在沙盒的保存地址:
/Users/admin/Library/Developer/CoreSimulator/Devices/95A0E48B-2AF9-45A0-83AE-6C065C293B5E/data/Containers/Data/Application/8279B407-F09D-4FD8-99F1-7695B1F9FDC1/Library/Caches
2-沙盒中緩存的16張圖片.png