iOS开发系列-NSOperation
概述
NSOperation是基于GCD的封装更加面向对象,在使用上也是有任务跟队列的概念,分别对应两个类NSOperation 、NSOperationQueue
NSOperation和NSOperationQueue实现多线程的具体步骤
- 现将需要执行的操作封装到一个NSOperation对象中。
- 然后将NSOperation对象添加到NSOperationQueue中
- 系统会自动将NSOperationQueue中的NSOperation取出来
- 将取出的NSOperation封装的操作放到一条线程中执行
NSOperation
NSOperation是一个抽象类,使用时候需要使用其子类。NSOperation总共有两个子类。
- NSInvocationOperation
- NSBlockOperation
开发中一般NSOperation子类通常与NSOperationQueue一起使用才能更好的开辟线程。
NSOperationQueue
NSOperation可以调用start方法类执行任务,但默认是同步的。如果将NSOperation添加到NSOperationQueue中执行,系统会自动异步执行NSOperation中的操作。
NSOperationQueue只用两种类型,分别是主队列跟非主队列(包含串行、并发)。两种队列的获取方式:
[NSOperationQueue mainQueue]; // 主队类
[[NSOperationQueue alloc] init]; // 非主队列
凡是添加到主队列的任务都是在主线程中执行。非主队列的任务会自动添加到子线程中执行。并发跟串行通过队列的maxConcurrentOperationCount决定。
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task) object:nil];
[queue addOperation:operation];
// [operation start];
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"------------%@", [NSThread currentThread]);
}];
// 添加额外的任务才会在子线程执行
[blockOperation addExecutionBlock:^{
NSLog(@"------------%@", [NSThread currentThread]);
}];
[queue addOperation:blockOperation];
// [blockOperation start];
}
- (void)task
{
NSLog(@"------------%@", [NSThread currentThread]);
}
一旦NSOperation添加进NSOperationQueue,无须调用NSOperation的start方法,内部自动回调用NSOperation的start。
开发中还可以自定义NSOperation的方式,重写main方法将任务封装进来。如果任务的代码比较多,在很多程序的很多地方都需要使用,建议采用这种方式。
#import "FMOperation.h"
@implementation FMOperation
- (void)main
{
// 封装任务
}
@end
NSOperationQueue的挂起和取消
设置NSOperationQueue的属性suspended为YES,内部的操作会暂停,在设置suspended为NO时内部的操作会恢复执行。
注意:当设置NSOperationQueue的suspended为YES时,当前的正在进行的NSOperation中任务会继续执行直到完毕后再暂停。
调用NSOperationQueue的cancelAllOperations方法相当于调用了内部所有NSOperation内部的cancel方法,一旦取消无法恢复。若想再次执行只能从新添加。
同样调用cancelAllOperations时执行到一半的NSOperationQueue是没办法中途停止下来直到该NSOperation执行完毕。
如果我们在自定义的NSOperation的main中封装了大量耗时的操作,苹果建议我们需要在任务中间做判断。提高性能
#import "FMOperation.h"
@implementation FMOperation
- (void)main
{
// 封装任务
for (NSInteger i=0; i<10000; i++) {
NSLog(@"download1-----------");
}
if (self.isCancelled) return;
for (NSInteger i=0; i<10000; i++) {
NSLog(@"download2-----------");
}
if (self.isCancelled) return;
for (NSInteger i=0; i<10000; i++) {
NSLog(@"download3-----------");
}
if (self.isCancelled) return;
}
@end
NSOperation的操作依赖和监听
默认情况下,添加进队列中操作并发执行时执行顺序是不可控的,这里可以通过设置依赖。并且可以跨队列设置NSOperation依赖。
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"---------------blockOperation1");
}];
NSBlockOperation *blockOperation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"---------------blockOperation2");
}];
NSBlockOperation *blockOperation3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"---------------blockOperation3");
}];
// 在添加之前设置依赖 让blockOperation3最后执行
[blockOperation3 addDependency:blockOperation1];
[blockOperation3 addDependency:blockOperation2];
[queue addOperation:blockOperation1];
[queue addOperation:blockOperation2];
[queue addOperation:blockOperation3];
}
通过Operation的completionBlock属性监听某个NSOoperation任务执行完毕。
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"---------------blockOperation1");
}];
NSBlockOperation *blockOperation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"---------------blockOperation2");
}];
NSBlockOperation *blockOperation3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"---------------blockOperation3");
}];
// 监听blockOperation2执行完毕
blockOperation2.completionBlock = ^{
// blockOperation2执行完毕
};
[queue addOperation:blockOperation1];
[queue addOperation:blockOperation2];
[queue addOperation:blockOperation3];
}
iOS开发系列-NSOperation的更多相关文章
- iOS开发系列--并行开发其实很容易
--多线程开发 概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的, ...
- iOS开发系列--Swift语言
概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...
- iOS开发系列文章(持续更新……)
iOS开发系列的文章,内容循序渐进,包含C语言.ObjC.iOS开发以及日后要写的游戏开发和Swift编程几部分内容.文章会持续更新,希望大家多多关注,如果文章对你有帮助请点赞支持,多谢! 为了方便大 ...
- iOS开发系列--App扩展开发
概述 从iOS 8 开始Apple引入了扩展(Extension)用于增强系统应用服务和应用之间的交互.它的出现让自定义键盘.系统分享集成等这些依靠系统服务的开发变成了可能.WWDC 2016上众多更 ...
- iOS开发系列--Swift进阶
概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...
- iOS开发系列--通知与消息机制
概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地 ...
- iOS开发系列--数据存取
概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储, ...
- iOS开发系列--网络开发
概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...
- iOS开发系列--C语言之基础知识
概览 当前移动开发的趋势已经势不可挡,这个系列希望浅谈一下个人对IOS开发的一些见解,这个IOS系列计划从几个角度去说IOS开发: C语言 OC基础 IOS开发(iphone/ipad) Swift ...
随机推荐
- thinkphp自动创建目录
自动创建目录 在第一次访问应用入口文件的时候,会显示如图所示的默认的欢迎页面,并自动生成了一个默认的应用模块Home. 接下来再看原来空的Application目录下面,已经自动生成了公共模块Comm ...
- eclipse打包插件net.sf.fjep.fatjar
eclipse打包插件安装 1)将net.sf.fjep.fatjar_0.0.32.jar拷贝到eclipse安装目录中的plugins目录下,然后重启eclipse即可. 软件获取方式: 链接:h ...
- 互联网公司java面试题(一)
1.JDK和JRE区别? JDK是整个JAVA的核心,包括了Java运行环境JRE,一堆Java工具和Java基础的类库.通过JDK开发人员将源码文件(java文件)编译成字节码文件(class文 件 ...
- 数据结构C++版-队列
一.概念 分类: 二.补充说明 1.<面向对象的队列设计>课程问答: 首先要明确数据结构和数据存储结构的概念. 数据结构是指数据对象之间的逻辑关系,例如二叉树,队列,栈等,而数据存储结构是 ...
- 转-pycharm建立项目
转自:https://blog.csdn.net/m0_37544464/article/details/79171913 本文针对环境已经配置好的Pycharm建立新项目 1.第一步 2.第二步 在 ...
- LeetCode 707. Design Linked List (设计链表)
题目标签:Linked List 题目让我们自己设计一个 linked list,可以是单向和双向的.这里选的是单向,题目并不是很难,但要考虑到所有的情况,具体看code. Java Solution ...
- 2019 牛客多校第一场 F Random Point in Triangle
题目链接:https://ac.nowcoder.com/acm/contest/881/F 题目大意 给定二维平面上 3 个整数表示的点 A,B,C,在三角形 ABC 内随机选一点 P,求期望$E ...
- SpringIOC中的注解配置
Spring中的注解是个好东西,可以简化我们的操作,但是使用了注解又会在一定的程度上增加程序的耦合度,xml中的配置写在了类中虽然简化了开发过程,但是或多或少的违背了开闭原则.所以在开发过程中要先明确 ...
- [课后作业] 第001讲:我和Python的第一次亲密接触 | 课后测试题的答案
0. Python 是什么类型的语言? Python是脚本语言 脚本语言(Scripting language)是电脑编程语言,因此也能让开发者藉以编写出让电脑听命行事的程序.以简单的方式快速完成某些 ...
- 22-Ubuntu-文件和目录命令-移动文件和目录-mv
mv 可以用来移动文件或目录,也可以给文件或目录重命名. 选项 含义 -i 覆盖文件前提示 1.移动文件和目录 1-1移动文件 例: 将当前目录下的123.txt文件移动到~/桌面/b/e目录下 mv ...