iOS 多线程iOS多线程等

iOS开发 自定义并发NSOperation实战

2017-01-21  本文已影响125人  MrZhaoCn

前一章节已经介绍了如何自定义并发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
上一篇 下一篇

猜你喜欢

热点阅读