iOS开发 自定义并发NSOperation实战

前一章节已经介绍了如何自定义并发NSOperation,本节将其应用到具体实例,如果自定义并发NSOperation不会,请移步http://www.jianshu.com/p/65629ba90d6a
在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;
@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

在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]; 
    //发送网络请求获取数据  
    [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 

20160914145257159.png

以上就是自定义并发NSOperation的一个简单应用,功能类似于SDWebImage.
代码地址:https://github.com/MrZhaoCn/iOS-NSOperation.git

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容