#import <UIKit/UIKit.h>
@interface DownLoadImageManager : NSObject
+ (instancetype)shareManager;
- (void)downloadOperationWithURLString:(NSString *)URLString finish:(void(^)(UIImage *image))finish;
- (void)cancelDownload:(NSString *)URLString;
- (void)clearMemory;
@end
#import "DownLoadImageManager.h"
#import "DownLoadOperation.h"
#import "NSString+Path.h"
@interface DownLoadImageManager ()
@property (nonatomic, strong) NSOperationQueue *queue;
@property (nonatomic, strong) NSMutableDictionary *operationCache;
@property (nonatomic, strong) NSMutableDictionary *imageCache;
@end
@implementation DownLoadImageManager
+ (instancetype)shareManager {
static dispatch_once_t onceToken;
static id instance;
dispatch_once(&onceToken, ^{
instance = [[self alloc]init];
});
return instance;
}
- (void)downloadOperationWithURLString:(NSString *)URLString finish:(void (^)(UIImage *))finish {
NSAssert(finish != nil, @"完成回调不能为空");
if ([self checkCache:URLString]) {
UIImage *image = [self.imageCache objectForKey:URLString];
finish(image);
return;
}
DownLoadOperation * op = [DownLoadOperation downloadOperationWithURLString:URLString finish:^(UIImage *image) {
[self.operationCache removeObjectForKey:URLString];
if (image) {
[self.imageCache setObject:image forKey:URLString];
}
finish(image);
}];
[self.queue addOperation:op];
[self.operationCache setObject:op forKey:URLString];
}
- (BOOL)checkCache:(NSString *)URLString {
if ([self.imageCache objectForKey:URLString]) {
NSLog(@"内存缓存");
return YES;
}
NSString *path = [URLString appendCache];
NSData *data = [NSData dataWithContentsOfFile:path];
UIImage *image = [UIImage imageWithData:data];
if (image) {
NSLog(@"沙盒缓存");
[self.imageCache setObject:image forKey:URLString];
return YES;
}
return NO;
}
- (void)cancelDownload:(NSString *)URLString {
DownLoadOperation *op = [self.operationCache objectForKey:URLString];
[op cancel];
}
- (NSMutableDictionary *)operationCache {
if (_operationCache == nil) {
_operationCache = [NSMutableDictionary dictionary];
}
return _operationCache;
}
- (NSMutableDictionary *)imageCache {
if (_imageCache == nil) {
_imageCache = [NSMutableDictionary dictionary];
}
return _imageCache;
}
- (NSOperationQueue *)queue {
if (_queue == nil) {
_queue = [[NSOperationQueue alloc]init];
_queue.maxConcurrentOperationCount = 6;
}
return _queue;
}
- (void)clearMemory {
[self.imageCache removeAllObjects];
[self.queue cancelAllOperations];
}
@end
#import <UIKit/UIKit.h>
@interface DownLoadOperation : NSOperation
+ (instancetype)downloadOperationWithURLString:(NSString *)URLString finish:(void(^)(UIImage *image))finish;
@end
#import "DownLoadOperation.h"
#import "NSString+Path.h"
@interface DownLoadOperation ()
@property (nonatomic, copy) NSString *URLString;
@property (nonatomic, copy) void(^finish)(UIImage *image);
@end
@implementation DownLoadOperation
- (void)main {
@autoreleasepool {
NSAssert(self.finish != nil, @"完成回调不能为空");
NSURL *url = [NSURL URLWithString:self.URLString];
NSData *data = [NSData dataWithContentsOfURL:url];
if (data) {
NSLog(@"%@",NSHomeDirectory());
[data writeToFile:[self.URLString appendCache] atomically:YES];
}
if (self.isCancelled) {
NSLog(@"操作已经被取消");
return;
}
UIImage *image = [UIImage imageWithData:data];
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
self.finish(image);
}];
}
}
+ (instancetype)downloadOperationWithURLString:(NSString *)URLString finish:(void (^)(UIImage *))finish {
DownLoadOperation *op = [[self alloc]init];
op.URLString = URLString;
op.finish = finish;
return op;
}
#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 <UIKit/UIKit.h>
@interface UIImageView (WebImage)
- (void)setImageWithURLString:(NSString *)URLString;
@end
#import "UIImageView+WebImage.h"
#import <objc/runtime.h>
#import "DownLoadImageManager.h"
@interface UIImageView ()
@property (nonatomic, copy) NSString *currentURL;
@end
@implementation UIImageView (WebImage)
- (void)setImageWithURLString:(NSString *)URLString {
self.image = nil;
if (![URLString isEqualToString:self.currentURL] && self.currentURL) {
[[DownLoadImageManager shareManager]cancelDownload:self.currentURL];
}
self.currentURL = URLString;
[[DownLoadImageManager shareManager]downloadOperationWithURLString:self.currentURL finish:^(UIImage *image) {
self.image = image;
}];
}
#define CZCurrentURL "currentURL"
- (NSString *)currentURL {
return objc_getAssociatedObject(self, CZCurrentURL);
}
- (void)setCurrentURL:(NSString *)currentURL {
objc_setAssociatedObject(self, CZCurrentURL, currentURL, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
@end