iOS开发 自定义并发NSOperation实战

来源:互联网 发布:windows多线程编程实例 编辑:程序博客网 时间:2024/05/16 11:47

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






1 0
原创粉丝点击