多线程:下载管理器(模拟 SDWebImage)
来源:互联网 发布:java字符串数组初始化 编辑:程序博客网 时间:2024/06/06 00:38
#import "ViewController.h"#import "DownLoadImageManager.h"#import "AppInfo.h"@interface ViewController ()@property (weak, nonatomic) IBOutlet UIImageView *imageView;@property (nonatomic, copy) NSString *currentURL; // 记录当前下载的URL@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. NSLog(@"%@",NSHomeDirectory());}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { NSArray *data = [AppInfo appInfoList]; // 连续点击的时候,只显示最后一张 AppInfo *app = data[arc4random_uniform(data.count)]; // 判断要下载的URL跟上一个下载的URL的关系 if (![app.icon isEqualToString:self.currentURL] && self.currentURL) { // 取消上一个下载操作 [[DownLoadImageManager shareManager]cancelDownload:self.currentURL]; } self.currentURL = app.icon; [[DownLoadImageManager shareManager]downloadOperationWithURLString:app.icon finish:^(UIImage *image) { self.imageView.image = image; }];}- (IBAction)cancel:(id)sender {}@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 ()// 图片下载的URLString@property (nonatomic, copy) NSString *URLString;// 下载完成之后的回调@property (nonatomic, copy) void(^finish)(UIImage *image);@end@implementation DownLoadOperation// 线程入口- (void)main { // 需要添加自动释放池 @autoreleasepool { // 断言 (只在debug模式下有作用)在上架之后不起作用 NSAssert(self.finish != nil, @"完成回调不能为空"); // 下载操作 // 首先要有网址 NSURL *url = [NSURL URLWithString:self.URLString]; // 接收二进制数据 NSData *data = [NSData dataWithContentsOfURL:url]; // 如果有数据就保存图片 if (data) { NSLog(@"%@",NSHomeDirectory()); // 2. 沙盒缓存 [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;}// SDWebImage 在start 方法中取消正在执行的操作 (已经提交了几千份代码)// 不管操作是否已经被取消,都会调用 start 方法// 如果重写start 方法来取消操作,很非常麻烦// 有兴趣可以去看SDWebImage 的 start 方法//- (void)start {// NSLog(@"cancel = %d",self.isCancelled);// if (self.isCancelled)return;////// NSLog(@"%s",__FUNCTION__);// [super start];////}@end
#import <UIKit/UIKit.h>@interface DownLoadImageManager : NSObject+ (instancetype)shareManager;- (void)downloadOperationWithURLString:(NSString *)URLString finish:(void(^)(UIImage *image))finish;- (void)cancelDownload:(NSString *)URLString;@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]; // SDWebImage 也是 6 _queue.maxConcurrentOperationCount = 6; } return _queue;}@end
0 0
- 多线程:下载管理器(模拟 SDWebImage)
- 多线程:下载图片(不用SDWebImage)
- 网络多线程下载图片(SDWebImage)
- 多线程:实现下载图片(使用 SDwebImage框架)
- 多线程:使用ImageView下载图片(模仿 SDWebImage)
- 多线程:使用ImageView分类下载图片(模仿 SDWebImage)
- 网络多线程-下载图片(不用SDWebImage框架)
- 多线程(四) SDWebImage,NSCache
- iOS 【Multithreading-多图下载数据展示案例(二级缓存)/模拟SDWebImage内部实现】
- 模拟多线程下载
- Android模拟多线程下载
- SDWebImage下载
- Java多线程文件下载管理器(未测试)
- SDWebImage在多线程下载图片时防止错乱的策略
- SDWebImage在多线程下载图片时防止错乱的策略
- 模拟迅雷下载程序 多线程
- 多线程06-(sdwebimage 总结3)
- 多线程: 自定义操作(模仿 SDWebImage)
- java和js实现aes加密解密
- 各种字符的限制输入
- dreamweaver制作静态网页第一天
- 【OpenCV】OpenCV3的第三天——core组件
- 对WindowListener接口的简单应用
- 多线程:下载管理器(模拟 SDWebImage)
- Tomcat之——Context []startup failed due to previous errors有效解决方式
- SQL Server 2012概述
- 【追求进步】字符串的排列
- 笔记 AsyncTask运行原理
- 修改tableView侧栏索引的背景色
- Java锁之自旋锁详解
- xcode7如何运行iOS10及iOS10以上,xcode8如何运行iOS10.1及10.1以上
- Winio64在64位系统中初始化失败问题