iOS开发多线程之NSOperation
NSInvocationOperation
The NSInvocationOperation
class is a concrete subclass of NSOperationthat you use to initiate an operation that consists of invoking a selector on a specified object. This class implements a non-concurrent operation.
根据苹果官方的解释说,NSInvocationOperation
是NSOperation
的一个子类,你可以初始化一个操作,该操作在一个指定的对象上去调用一个selector,并且NSOperation
这个类实现了一个非并发的操作。具体怎么使用NSInvocationOperation
这个类呢?
NSInvocationOperation的创建
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest) object:nil];
NSInvocationOperation创建完成之后,怎么触发该线程的执行?一共有两种方式执行该线程
方式一:
//调用start方法执行,此执行方式在主线程中执行,没有开辟新的线程
// ThreadDemo[20397:12090175] ------------<NSThread: 0x60400007da00>{number = 1, name = main}-----
[operation start];
调用start方法执行此线程,但是使用此方法,并不会开辟新的线程来执行代码
方式二:
//加入到队列中去执行,此种方式会开辟线程,在新的线程中执行代码
// ThreadDemo[20432:12091400] ------------<NSThread: 0x600000273240>{number = 3, name = (null)}-----
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation];
根据打印信息可以看出,把创建的NSInvocationOperation加入到一个queue队列中去执行,会开辟新的线程执行任务。
NSBlockOperation
The NSBlockOperation
class is a concrete subclass of NSOperationthat manages the concurrent execution of one or more blocks. You can use this object to execute several blocks at once without having to create separate operation objects for each. When executing more than one block, the operation itself is considered finished only when all blocks have finished executing.NSBlockOperation
类是NSOperation
的一个具体子类,它管理一个或多个块的并发执行。您可以使用这个对象一次执行几个块,而不必为每个块创建单独的操作对象。当执行多个块时,只有当所有块都完成执行时,才考虑操作本身。
NSBlockOperation的创建
//创建NSBlockOperation线程方式1
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"------operation------%@-----", [NSThread currentThread]);
}];
[operation start];
//创建NSBlockOperation线程方式2
NSBlockOperation *operation1 = [[NSBlockOperation alloc] init];
[operation1 addExecutionBlock:^{
NSLog(@"------operation1------%@-----", [NSThread currentThread]);
}];
[operation1 start];
这样创建后调用start方法,同样在主线程中执行,下面看看把NSBlockOperation添加到queue队列中去执行
NSBlockOperation *operation = [[NSBlockOperation alloc] init];
[operation addExecutionBlock:^{
NSLog(@"------block1------%@-----", [NSThread currentThread]);
}];
[operation addExecutionBlock:^{
NSLog(@"------block2------%@-----", [NSThread currentThread]);
}];
[operation addExecutionBlock:^{
NSLog(@"------block3------%@-----", [NSThread currentThread]);
}];
[operation addExecutionBlock:^{
NSLog(@"------block4------%@-----", [NSThread currentThread]);
}];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation];
可以看出,加入到queue队列中的任务全都是异步执行
使用NSOperationQueue来创建任务
/**
使用queue队列来自己添加任务并执行
*/
- (void)testOperationQueue {
//创建queue队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//添加任务
[queue addOperationWithBlock:^{
NSLog(@"------block1------%@-----", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"------block2------%@-----", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"------block3------%@-----", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"------block4------%@-----", [NSThread currentThread]);
}];
}
可以看出,使用queue队列来创建任务,省去了创建NSInvocationOperation
和NSBlockOperation
再加入到队列中执行。
上面列出了三种实现NSOperation
创建多线程的方式,在具体的工作中,使用哪种方式还是要根据工作需要具体对待。
队列的使用----依赖执行任务
有这个一个场景:任务3的执行依赖于任务2,任务2的执行依赖于任务1,相当于一个串行队列,只有当前面一个执行完成之后才开始下一个任务的执行,下面看看具体的实现方式:
/**
使用场景一:任务的依赖执行
*/
- (void)testDepenceyOperation {
//创建要执行的任务
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"------operation1------%@-----", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"------operation2------%@-----", [NSThread currentThread]);
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"------operation3------%@-----", [NSThread currentThread]);
}];
//给任务添加依赖,任务3依赖任务2,任务2依赖任务1
[operation3 addDependency:operation2];
[operation2 addDependency:operation1];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
}
队列的使用---设置最大并发数
设置最大并发数量,为了保证app的整个生命周期不会占用过多的资源,在有大量并发线程执行的时候,一定要进行设置,不然可能会造成app闪退。
- (void)testMacConcurrentOperationCount {
//创建queue队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//设置线程的最大并发数量
queue.maxConcurrentOperationCount = 3;
//添加任务
[queue addOperationWithBlock:^{
NSLog(@"------block1------%@-----", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"------block2------%@-----", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"------block3------%@-----", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"------block4------%@-----", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"------block5------%@-----", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"------block6------%@-----", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
NSLog(@"------block7------%@-----", [NSThread currentThread]);
}];
}
iOS开发多线程之NSOperation的更多相关文章
- iOS开发-多线程之GCD(Grand Central Dispatch)
Grand Central Dispatch(GCD)是一个强有力的方式取执行多线程任务,不管你在回调的时候是异步或者同步的,可以优化应用程序支持多核心处理器和其他的对称多处理系统的系统.开发使用的过 ...
- iOS开发多线程之NSThread
一.NSThread的属性与方法 1.NSThread 类方法 类方法,顾名思义通过类名直接调用的方法 1. + (void)detachNewThreadWithBlock:(void (^)(vo ...
- iOS开发多线程之GCD
Grand Central Dispatch(GCD)是异步执行任务的技术之一.一般将应用程序中记述的线程管理用的代码在系统级中实现.开发者只需要定义想执行的任务并追加到适当的Dispatch Que ...
- iOS开发多线程篇—自定义NSOperation
iOS开发多线程篇—自定义NSOperation 一.实现一个简单的tableView显示效果 实现效果展示: 代码示例(使用以前在主控制器中进行业务处理的方式) 1.新建一个项目,让控制器继承自UI ...
- 多线程之NSOperation
关于多线程会有一系列如下:多线程之概念解析 多线程之pthread, NSThread, NSOperation, GCD 多线程之NSThread 多线程之NSOperation 多线程之GCD
- iOS多线程之NSOperation详解
使用NSOperation和NSOperationQueue进行多线程开发,只要将一个NSOperation(实际开发中需要使用其子类 NSInvocationOperation,NSBlockOpe ...
- iOS开发之多线程技术——NSOperation篇
本篇将从四个方面对iOS开发中使用到的NSOperation技术进行讲解: 一.什么是NSOperation 二.我们为什么使用NSOperation 三.在实际开发中如何使用NSOperation ...
- 多线程之NSOperation简介
在iOS开发中,为了提升用户体验,我们通常会将操作耗时的操作放在主线程之外的线程进行处理.对于正常的简单操作,我们更多的是选择代码更少的GCD,让我们专注于自己的业务逻辑开发.NSOperation在 ...
- 记Booking.com iOS开发岗位线上笔试
今晚参加了Booking的iOS职位线上笔试,结束后方能简单归纳一下. 关于测试内容: Booking采用了HackerRank作为测试平台,测试总时长为75分钟,总计4道题. 测试之前我很紧张,因为 ...
随机推荐
- 通过注解配置Bean
之前说的三种配置方式,都是使用XML配置,现在我们说说使用注解配置Bean. 这部分内容主要分为两个部分:使用注解配置Bean,使用注解配置Bean属性. 在classpath中扫描组件 组件扫描:S ...
- 设置 sql_mode
MySQL 的 sql_mode 合理设置 sql_mode 是个很容易被忽视的变量,默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入.在生产环境必须将这个值设置为严格模 ...
- 微服务下的容器部署和管理平台Rancher
Rancher是什么 Rancher是一个开源的企业级容器管理平台.通过Rancher,企业再也不必自己使用一系列的开源软件去从头搭建容器服务平台.Rancher提供了在生产环境中使用的管理Docke ...
- Burnside引理的感性证明
\(Burnside\)引理的感性证明: 其中:\(G\)是置换集合,\(|G|\)是置换种数,\(T_i\)是第\(i\)类置换中的不动点数. \[L = \frac{1}{|G|} * \sum ...
- Numpy 系列(七)- 常用函数
在了解了 Numpy 的基本运算操作,下面来看下 Numpy常用的函数. 数学运算函数 add(x1,x2 [,out]) 按元素添加参数,等效于 x1 + x2 subtract(x1,x2 ...
- GO语言系列(二)- 基本数据类型和操作符
一.文件名 & 关键字 & 标识符 1.所有go源码以.go结尾 2.标识符以字母或下划线开头,大小写敏感 3._是特殊标识符,用来忽略结果 4.保留关键字 二.Go程序的基本结构 p ...
- Entity Framework入门教程(4)---EF中的实体关系
这一节将总结EF是怎么管理实体之间的关系.EF与数据库一样支持三种关系类型:①一对一 ,②一对多,③多对多. 下边是一个SchoolDB数据库的实体数据模型,图中包含所有的实体和各个实体间的关系.通过 ...
- JAVA第一周学习
新学期伊始,六门专业课,课课重要,无法抉择重心,但日子还是要过的,而且要精细的过,不能得过且过 JAVA第一周任务 一:学习第一章视频 二:使用JDB调试JAVA 三:输入调试教材上代码,并把代码上传 ...
- spring boot打包
1.application继承SpringBootServletInitializer 重写configure方法如下图 2.去掉项目中多余的main方法 3.将pom.xml打包改为war包 4. ...
- [物理学与PDEs]第3章第5节 一维磁流体力学方程组 5.2 一维磁流体力学方程组的 Lagrange 形式
由 $$\bex \cfrac{\p \rho}{\p t}&+u_1\cfrac{\p \rho}{\p x}+\rho\cfrac{\p u_1}{\p x}=0, \eex$$ 我们可以 ...