前一章节已经介绍了如何自定义并发NSOperation,本节将其应用到具体实例,如果自定义并发NSOperation不会,请移步:http://blog.csdn.net/huiqin131460/article/details/52526752
在ZCCurrentOperation.h文件中代码如下:
// // ZCCurrentOperation.h // 自定义非并发NSOPeration // // Created by MrZhao on 16/9/13. // Copyright © 2016年 MrZhao. All rights reserved. // /* *自定义并发的NSOperation需要以下步骤: 1.start方法:该方法必须实现, 2.main:该方法可选,如果你在start方法中定义了你的任务,则这个方法就可以不实现,但通常为了代码逻辑清晰,通常会在该方法中定义自己的任务 3.isExecuting isFinished 主要作用是在线程状态改变时,产生适当的KVO通知 4.isConcurrent :必须覆盖并返回YES; */ #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @class ZCCurrentOperation;</span> <span style="font-family: Arial, Helvetica, sans-serif;">//协议主要用于在下载完图片后通知主线程更新UI</span> @protocol currentOperationDelegate <NSObject> -(void)downLoadOperation:(ZCCurrentOperation*)operation didFishedDownLoad:(UIImage *)image; @end @interface ZCCurrentOperation : NSOperation { BOOL executing; BOOL finished; } @property (nonatomic, copy)NSString *urlStr; @property (nonatomic, strong)NSIndexPath *indexPath; @property (nonatomic, weak)id<currentOperationDelegate>delegate; @end<pre name="code" class="objc">
在ZCCurrentOperation.m文件中代码如下:
// // ZCCurrentOperation.m // 自定义非并发NSOPeration // https://github.com/MrZhaoCn/iOS-NSOperation.git // Created by MrZhao on 16/9/13. // Copyright © 2016年 MrZhao. All rights reserved. // #import "ZCCurrentOperation.h" @implementation ZCCurrentOperation - (id)init { if(self = [super init]) { executing = NO; finished = NO; } return self; } - (BOOL)isConcurrent { return YES; } - (BOOL)isExecuting { return executing; } - (BOOL)isFinished { return finished; } - (void)start { //第一步就要检测是否被取消了,如果取消了,要实现相应的KVO if ([self isCancelled]) { [self willChangeValueForKey:@"isFinished"]; finished = YES; [self didChangeValueForKey:@"isFinished"]; return; } //如果没被取消,开始执行任务 [self willChangeValueForKey:@"isExecuting"]; [NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil]; executing = YES; [self didChangeValueForKey:@"isExecuting"]; } - (void)main { @try { @autoreleasepool { //在这里定义自己的并发任务 NSLog(@"自定义并发操作NSOperation"); NSURL *url=[NSURL URLWithString:self.urlStr]; NSData *data=[NSData dataWithContentsOfURL:url]; UIImage *imgae=[UIImage imageWithData:data]; //图片下载完毕后,通知代理 if ([self.delegate respondsToSelector:@selector(downLoadOperation:didFishedDownLoad:)]) { dispatch_async(dispatch_get_main_queue(), ^{//回到主线程,传递数据给代理对象 [self.delegate downLoadOperation:self didFishedDownLoad:imgae]; }); } NSThread *thread = [NSThread currentThread]; NSLog(@"%@",thread); //任务执行完成后要实现相应的KVO [self willChangeValueForKey:@"isFinished"]; [self willChangeValueForKey:@"isExecuting"]; executing = NO; finished = YES; [self didChangeValueForKey:@"isExecuting"]; [self didChangeValueForKey:@"isFinished"]; } } @catch (NSException *exception) { } } @end
控制器的代码如下:
// // ViewController.m // 自定义并发NSOperation // // Created by MrZhao on 16/9/13. // Copyright © 2016年 MrZhao. All rights reserved. // #import "ViewController.h" #import "ZCCurrentOperation.h" #import "ZCNetWorkingTool.h" #import "MJExtension.h" #import "ZCLiveUser.h" @interface ViewController () <UITableViewDataSource,UITableViewDelegate,currentOperationDelegate> @property (nonatomic, strong)NSMutableArray *dataSource; @property (nonatomic, strong)NSOperationQueue *myQueue; @property (nonatomic, strong)UITableView *tableView; @property (nonatomic, strong)NSMutableDictionary *operations; @property (nonatomic, strong)NSMutableDictionary *images; @end @implementation ViewController static int page = 1; #pragma mark life cycle - (void)viewDidLoad { [super viewDidLoad]; [self.view addSubview:self.tableView]; } - (void)viewWillAppear:(BOOL)animated { //发送网络请求获取数据 [self loadData]; } - (void)viewDidLayoutSubviews { self.tableView.frame = self.view.bounds; } #pragma mark tableViewDataSourece - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.dataSource.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *ID = @"CELL"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; } if (self.dataSource.count >0) { ZCLiveUser *liveUser = self.dataSource[indexPath.row]; //保证一个url对应一个image对象 UIImage *image = self.images[liveUser.photo]; if (image) {//缓存中有图片 cell.imageView.image = image; } else { // 缓存中没有图片,得下载 //先设置一张占位图片 cell.imageView.image = [UIImage imageNamed:@"reflesh1_60x55"]; ZCCurrentOperation *operation = self.operations[liveUser.photo]; if (operation) {//正在下载 //什么都不做 }else { //当前没有下载,那就创建操作 operation = [[ZCCurrentOperation alloc]init]; operation.urlStr = liveUser.photo; operation.indexPath = indexPath; operation.delegate = self; [self.myQueue addOperation:operation];//异步下载 self.operations[liveUser.photo] = operation; } } } return cell; } - (void)loadData { NSString *url = [NSString stringWithFormat:@"http://live.9158.com/Room/GetNewRoomOnline?page=%ld",(unsigned long)page]; ZCNetWorkingTool *tool = [ZCNetWorkingTool shareNetWorking]; [tool GETWithURL:url parameters:nil sucess:^(id reponseBody) { NSArray *array = reponseBody[@"data"][@"list"]; //将字典数组转成模型数组 NSArray *arrayM =[ZCLiveUser objectArrayWithKeyValuesArray:array]; if (arrayM.count>0) { [self.dataSource addObjectsFromArray:arrayM]; [self.tableView reloadData]; } } failure:^(NSError *error) { NSLog(@"数据加载失败"); }]; } - (void)downLoadOperation:(ZCCurrentOperation *)operation didFishedDownLoad:(UIImage *)image{ //1.移除执行完毕的操作 [self.operations removeObjectForKey:operation.urlStr]; //2.将图片放到缓存中 self.images[operation.urlStr]=image; //3.刷新表格(只刷新下载的那一行) [self.tableView reloadRowsAtIndexPaths:@[operation.indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; } #pragma mark懒加载相关 - (NSOperationQueue *)myQueue { if (!_myQueue) { self.myQueue = [[NSOperationQueue alloc] init]; self.myQueue.maxConcurrentOperationCount = 3; } return _myQueue; } - (UITableView *)tableView { if (!_tableView) { self.tableView = [[UITableView alloc] init]; self.tableView.delegate = self; self.tableView.dataSource = self; } return _tableView; } - (NSMutableArray *)dataSource { if (_dataSource == nil) { _dataSource = [NSMutableArray array]; } return _dataSource; } - (NSMutableDictionary *)operations { if (!_operations) { self.operations = [NSMutableDictionary dictionary]; } return _operations; } - (NSMutableDictionary *)images { if (!_images) { self.images = [NSMutableDictionary dictionary]; } return _images; } @end打印结果如下:
以上就是自定义并发NSOperation的一个简单应用,功能类似于SDWebImage.
代码地址:
https://github.com/MrZhaoCn/iOS-NSOperation.git