概述

NSOperation是基于GCD的封装更加面向对象,在使用上也是有任务跟队列的概念,分别对应两个类NSOperation 、NSOperationQueue

NSOperation和NSOperationQueue实现多线程的具体步骤

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的更多相关文章

  1. iOS开发系列--并行开发其实很容易

    --多线程开发 概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的, ...

  2. iOS开发系列--Swift语言

    概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...

  3. iOS开发系列文章(持续更新……)

    iOS开发系列的文章,内容循序渐进,包含C语言.ObjC.iOS开发以及日后要写的游戏开发和Swift编程几部分内容.文章会持续更新,希望大家多多关注,如果文章对你有帮助请点赞支持,多谢! 为了方便大 ...

  4. iOS开发系列--App扩展开发

    概述 从iOS 8 开始Apple引入了扩展(Extension)用于增强系统应用服务和应用之间的交互.它的出现让自定义键盘.系统分享集成等这些依靠系统服务的开发变成了可能.WWDC 2016上众多更 ...

  5. iOS开发系列--Swift进阶

    概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...

  6. iOS开发系列--通知与消息机制

    概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地 ...

  7. iOS开发系列--数据存取

    概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储, ...

  8. iOS开发系列--网络开发

    概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...

  9. iOS开发系列--C语言之基础知识

    概览 当前移动开发的趋势已经势不可挡,这个系列希望浅谈一下个人对IOS开发的一些见解,这个IOS系列计划从几个角度去说IOS开发: C语言 OC基础 IOS开发(iphone/ipad) Swift ...

随机推荐

  1. hive的复合数据类型

    hive中的复合数据类型 Array array中的数据为相同类型,例如,假如array A中元素['a','b','c'],则A[1]的值为'b' 数据结构如下: zhangsan beijing, ...

  2. SP2713 GSS4 - Can you answer these queries IV(线段树)

    传送门 解题思路 大概就是一个数很少次数的开方会开到\(1\),而\(1\)开方还是\(1\),所以维护一个和,维护一个开方标记,维护一个区间是否全部为\(1/0\)的标记.然后每次修改时先看是否有全 ...

  3. NOIp2018集训test-9-5(am)

    Problem A. maze 递归处理,题解写得真简单. 我大概这辈子也写不出来这种东西吧. Problem B. count 容易发现合法的数中一定有且仅有两个数加起来等于10,其他数两两配对加起 ...

  4. NX二次开发-创建图纸尺寸表达式抑制UF_DRF_add_controlling_exp

    #include <uf.h> #include <uf_modl.h> #include <uf_drf.h> #include <uf_obj.h> ...

  5. 开发中运行mysql脚本,发现提示mysql提示Column count doesn't match value count at row 1错误

    开发中运行mysql脚本,发现提示mysql提示Column count doesn't match value count at row 1错误, 调试后发现是由于写的SQL语句里列的数目和后面的值 ...

  6. c++-字符串和时间操作

    C++ 字符串 C++ 提供了以下两种类型的字符串表示形式: C 风格字符串 C++ 引入的 string 类类型 C 风格字符串 C 风格的字符串起源于 C 语言,并在 C++ 中继续得到支持.字符 ...

  7. icmp隧道--icmpsh

    本地:ubantu 目标主机:windows 在ubantu上关闭自带的icmp回应 sysctl -w net.ipv4.icmp_echo_ighore_all=1 ubantu上启动 pip i ...

  8. 如何理解CUDA中的cudaMalloc()的参数

    首先看下此运行时函数的原型: cudaError_t cudaMalloc (void **devPtr, size_t size ); 主要的第一个参数.为什么是两个星星呢?用个例子来说明下. fl ...

  9. jquery操作html元素之( 尺寸)

    jQuery 提供多个处理尺寸的重要方法: width() height() innerWidth() innerHeight() outerWidth() outerHeight() jQuery ...

  10. 16-MySQL-Ubuntu-数据表的查询-分组与聚合(五)

    分组(group by)一般与聚合结合使用 (1)查询按性别分组 select gender from students group by gender; (2)查询按性别分组并统计每组的数量sele ...