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
打印结果如下:
代码地址:
https://github.com/MrZhaoCn/iOS-NSOperation.git
1 0
- iOS开发 自定义并发NSOperation实战
- iOS开发 自定义NSOPeration
- iOS开发多线程-自定义NSOperation
- iOS开发之自定义NSOperation
- iOS开发多线程篇—自定义NSOperation
- iOS开发多线程篇—自定义NSOperation
- iOS开发多线程篇—自定义NSOperation
- iOS开发多线程篇—自定义NSOperation
- iOS开发实践之cell下载图片(自定义NSOperation)
- iOS开发—自定义NSOperation子类下载图片
- 【iOS开发】NSOperation
- IOS开发 - 多线程 NSOperation
- iOS并发编程(上)-- NSOperation queue
- IOS多线程开发之NSOperation
- iOS开发之多线程NSOperation
- iOS开发 - 多线程之NSOperation
- iOS多线程开发之NSOperation
- [iOS]NSOperation的start与main,并发与非并发。
- android webview js交互 第一节 (java和js交互)
- ORA-01940:无法删除当前已连接的用户
- 我喜欢的Notepad++插件
- C ++头文件的十大错误,如何解决这些问题
- linux系统中xshell工具创建文件夹、复制、删除命令的使用
- iOS开发 自定义并发NSOperation实战
- 找出元素 item 在给定数组 arr 中的位置
- 代理模式详解
- Handler消息传递机制——源码赏析
- 1、Ubuntu下安装软件报错
- 降低方法
- mybatis配置参数及默认值
- uiautomator 2.0 android 6.0读取SD卡权限获取
- 全国省市县区域信息最新数据库脚本(mysql版本)