自定义NSOperation
2015-12-27 02:59
411 查看
通过上篇文章的学习我们知道, NSOperation系统自带的方法无论是取消还是挂起操作只能控制队列中的操作, 都无法操纵正在线程中运行的操作; 下面我们通过自定义NSOperation
代码调用
对于自定义操作,只要重写了 main 方法,当队列调度操作执行时,会自动运行 main 方法
目标二:给自定义参数传递参数
定义属性
代码调用
注意: 只有将操作添加到队列中操作才会执行, 也就是说才会执行main函数; 这时参数也就传递到操作中啦;
目标3: 如何回调?
利用系统提供的 CompletionBlock 属性
1> 只要设置了 CompletionBlock,当操作执行完毕后,就会被自动调用
2> CompletionBlock 既不在主线程也不在操作执行所在线程
3> CompletionBlock 无法传递参数
自己定义回调 Block,在操作结束后执行
1> 定义属性
2> 设置自定义回调
3> 耗时操作后执行回调
实现类方法
方法调用
添加多个下载操作
内存警告时取消所有操作
cancelAllOperations 会向队列中的所有操作发送 Cancel 消息
调整 main 方法,在关键节点判断
知识补充:
NSOperation的start与main函数
队列调度操作时,首先执行 start 方法将线程放入可调度线程池
操作执行时的入口是 main 方法
start方法默认会判断线程状态, 如果状态已经完成或取消,就不会调用main方法
如果操作没有执行, 接收到cancel消息, start方法同样会被调用
准备工作
自定义 DownloadImageOperation 继承自 NSOperation代码调用
// 实例化自定义操作 DownloadImageOperation *op = [[DownloadImageOperation alloc] init]; // 将自定义操作添加到下载队列 [self.downloadQueue addOperation:op];
需求驱动开发
目标一: 设置自定义操作的执行入口对于自定义操作,只要重写了 main 方法,当队列调度操作执行时,会自动运行 main 方法
- (void)main { @autoreleasepool { NSLog(@"%@", [NSThread currentThread]); } }
目标二:给自定义参数传递参数
定义属性
/// 要下载图像的 URL 字符串 @property (nonatomic, copy) NSString *URLString;
代码调用
// 实例化自定义操作 DownloadImageOperation *op = [[DownloadImageOperation alloc] init]; // 设置操作属性 op.URLString = @"https://www.baidu.com/img/bdlogo.png"; // 将自定义操作添加到下载队列,操作启动后会执行 main 方法 [self.downloadQueue addOperation:op];
注意: 只有将操作添加到队列中操作才会执行, 也就是说才会执行main函数; 这时参数也就传递到操作中啦;
目标3: 如何回调?
利用系统提供的 CompletionBlock 属性
// 设置完成回调 [op setCompletionBlock:^{ NSLog(@"完成 %@", [NSThread currentThread]); }];
1> 只要设置了 CompletionBlock,当操作执行完毕后,就会被自动调用
2> CompletionBlock 既不在主线程也不在操作执行所在线程
3> CompletionBlock 无法传递参数
自己定义回调 Block,在操作结束后执行
1> 定义属性
/// 完成回调 Block @property (nonatomic, copy) void (^finishedBlock)(UIImage *image);
2> 设置自定义回调
// 设置自定义完成回调 [op setFinishedBlock:^(UIImage *image) { NSLog(@"finished %@ %@", [NSThread currentThread], image); }];
3> 耗时操作后执行回调
// 判断自定义回调是否存在 if (self.finishedBlock != nil) { // 通常为了简化调用方的代码,异步操作结束后的回调,大多在主线程 [[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.finishedBlock(@"hello"); }]; }
目标4: 简化操作创建
定义类方法+ (instancetype)downloadImageOperationWithURLString:(NSString *)URLString finished:(void (^)(UIImage *image))finished;
实现类方法
+ (instancetype)downloadImageOperationWithURLString:(NSString *)URLString finished:(void (^)(UIImage *))finished { DownloadImageOperation *op = [[DownloadImageOperation alloc] init]; op.URLString = URLString; op.finishedBlock = finished; return op; }
方法调用
// 使用类方法实例化下载操作 DownloadImageOperation *op = [DownloadImageOperation downloadImageOperationWithURLString:@"http://www.baidu.com/img/bdlogo.png" finished:^(UIImage *image) { NSLog(@"%@", image); }]; // 将自定义操作添加到下载队列,操作启动后会执行 main 方法 [self.downloadQueue addOperation:op];
取消操作
在关键节点进行判断isCancelled添加多个下载操作
for (int i = 0; i < 10; ++i) { NSString *urlString = [NSString stringWithFormat:@"http://www.xxx.com/%04d.png", i]; DownloadImageOperation *op = [DownloadImageOperation downloadImageOperationWithURLString:urlString finished:^(UIImage *image) { NSLog(@"===> %@", image); }]; // 将自定义操作添加到下载队列,操作启动后会执行 main 方法 [self.downloadQueue addOperation:op]; }
内存警告时取消所有操作
- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; [self.downloadQueue cancelAllOperations]; }
cancelAllOperations 会向队列中的所有操作发送 Cancel 消息
调整 main 方法,在关键节点判断
- (void)main { NSLog(@"%s", __FUNCTION__); @autoreleasepool { NSLog(@"下载图像 %@", self.URLString); // 模拟延时 [NSThread sleepForTimeInterval:1.0]; if (self.isCancelled) { NSLog(@"1.--- 返回"); return; } // 判断自定义回调是否存在 if (self.finishedBlock != nil) { // 通常为了简化调用方的代码,异步操作结束后的回调,大多在主线程 [[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.finishedBlock(self.URLString); }]; } } }
知识补充:
NSOperation的start与main函数
队列调度操作时,首先执行 start 方法将线程放入可调度线程池
操作执行时的入口是 main 方法
start方法默认会判断线程状态, 如果状态已经完成或取消,就不会调用main方法
如果操作没有执行, 接收到cancel消息, start方法同样会被调用
相关文章推荐
- 基于rails的schedule网站开发(18):关于取不到1对1关系表中值的问题
- Looper类、主线程工作线程通信
- Centos7.1下安装Boost
- 文本处理 grep 与 sed
- 每天一个Linux之cat命令
- Linux内核源代码解析之——小弟我与神童聊Linux内核
- 抛弃编程语言的偏见——对话百度架构师
- Linux ->> UBuntu 14.04 LTE下设置静态IP地址
- 图片的copy,从一个目录复制到另一个目录
- DNS相关概念
- pop动画原理详解
- 阿岳之_Centos7.1_编辑器sed初级篇(1)
- POJ-3258 River Hopscotch
- 在Linux上批量处理邮件地址
- iOS 新建项目架构规范
- S5PV210环境搭建:arm-linux-gcc: 没有那个文件或目录
- Linux 常用命令汇总
- Centos修炼----->Centos7之Gcc安装
- linux虚拟机问题备忘
- django-nginx-uwsgi