#import <Foundation/Foundation.h>
@interface NSString (Path)
- (NSString *)appendDocument;
- (NSString *)appendCache;
- (NSString *)appendTmp;
@end
#import "NSString+Path.h"
@implementation NSString (Path)
- (NSString *)appendDocument {
NSString *root = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
return [root stringByAppendingPathComponent:[self lastPathComponent]];
}
- (NSString *)appendCache {
NSString *root = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
return [root stringByAppendingPathComponent:[self lastPathComponent]];
}
- (NSString *)appendTmp {
NSString *root = NSTemporaryDirectory();
return [root stringByAppendingPathComponent:[self lastPathComponent]];
}
@end
#import "ViewController.h"
#import "AppInfo.h"
#import "AppInfoCell.h"
#import "NSString+Path.h"
#define CZWeakSelf __weak typeof(self) weakSelf = self;
@interface ViewController ()
@property (nonatomic, strong) NSArray *data;
@property (nonatomic, strong) NSOperationQueue *download;
@property (nonatomic, strong) NSMutableDictionary *operationCache;
@property (nonatomic, strong) NSMutableDictionary *imageCache;
@property (nonatomic, strong) NSMutableArray *blackList;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark - tableview 代理 & 数据源
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.data.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *ID = @"Cell";
AppInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:ID forIndexPath:indexPath];
AppInfo *app = self.data[indexPath.row];
cell.nameLabel.text = app.name;
cell.downloadLabel.text = app.download;
cell.iconView.image = [UIImage imageNamed:@"user_default"];
if ([self.imageCache objectForKey:app.icon] != nil) {
cell.iconView.image = [self.imageCache objectForKey:app.icon];
NSLog(@"从内存加载图片");
return cell;
}
NSString *path = [app.icon appendCache];
NSData *data = [NSData dataWithContentsOfFile:path];
if (data) {
NSLog(@"沙盒缓存");
UIImage *image = [UIImage imageWithData:data];
[self.imageCache setObject:image forKey:app.icon];
cell.iconView.image = image;
return cell;
}
if ([self.operationCache objectForKey:app.icon]) {
NSLog(@"图片正在下载");
return cell;
}
if ([self.blackList containsObject:app.icon]) {
NSLog(@"黑名单不需要再去下载");
return cell;
}
[self downloadImage:indexPath];
return cell;
}
- (void)downloadImage:(NSIndexPath *)indexPath {
AppInfo *app = self.data[indexPath.row];
CZWeakSelf
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSURL *url = [NSURL URLWithString:app.icon];
NSData *data = [NSData dataWithContentsOfURL:url];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[weakSelf.operationCache removeObjectForKey:app.icon];
UIImage *image = [UIImage imageWithData:data];
if (image) {
[data writeToFile:[app.icon appendCache] atomically:YES];
[weakSelf.imageCache setObject:image forKey:app.icon];
[weakSelf.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
}else {
[self.blackList addObject:app.icon];
}
}];
}];
[self.operationCache setObject:op forKey:app.icon];
[self.download addOperation:op];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 80;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"%@",self.operationCache);
}
#pragma mark - 懒加载
- (NSArray *)data {
if (_data == nil) {
_data = [AppInfo appInfoList];
}
return _data;
}
- (NSOperationQueue *)download {
if (_download == nil) {
_download = [[NSOperationQueue alloc]init];
}
return _download;
}
- (NSMutableDictionary *)operationCache {
if (_operationCache == nil) {
_operationCache = [NSMutableDictionary dictionary];
}
return _operationCache;
}
- (NSMutableDictionary *)imageCache {
if (_imageCache == nil) {
_imageCache = [NSMutableDictionary dictionary];
}
return _imageCache;
}
- (NSMutableArray *)blackList {
if (_blackList == nil) {
_blackList = [NSMutableArray array];
}
return _blackList;
}
- (void)dealloc {
NSLog(@"走了");
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
NSLog(@"内存警告");
[self.imageCache removeAllObjects];
[self.download cancelAllOperations];
[self.operationCache removeAllObjects];
}
@end
#import <UIKit/UIKit.h>
@interface AppInfo : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *icon;
@property (nonatomic, copy) NSString *download;
+ (instancetype)appInfoWithDict:(NSDictionary *)dict;
+ (NSArray *)appInfoList;
@end
#import "AppInfo.h"
@implementation AppInfo
+ (instancetype)appInfoWithDict:(NSDictionary *)dict {
AppInfo *app = [[self alloc]init];
[app setValuesForKeysWithDictionary:dict];
return app;
}
+ (NSArray *)appInfoList {
NSString *path = [[NSBundle mainBundle]pathForResource:@"apps.plist" ofType:nil];
NSArray *data = [NSArray arrayWithContentsOfFile:path];
NSMutableArray *appList = [NSMutableArray arrayWithCapacity:data.count];
[data enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
AppInfo *app = [AppInfo appInfoWithDict:obj];
[appList addObject:app];
}];
return appList.copy;
}
@end
#import <UIKit/UIKit.h>
@interface AppInfoCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (weak, nonatomic) IBOutlet UILabel *downloadLabel;
@end
#import "AppInfoCell.h"
@implementation AppInfoCell
- (void)awakeFromNib {
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
}
@end