博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS--多线程之NSOperation
阅读量:6834 次
发布时间:2019-06-26

本文共 3647 字,大约阅读时间需要 12 分钟。

hot3.png

做一下整理,与大家分享,不足之处请留言:

使用NSOperation时,需要使用其子类:子类有三种方式

1.NSInvocationOperation   2.NSBlockOperation   3.自定义子类继承NSOperation,实现内部相应的方法

NSInvocationOperation 2个初始化方法

- (id)initWithTarget:(id)target selector:(SEL)sel object:(nullable id)arg;

- (void)start;//执行操作

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];

[operation start];

注意:默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作。只有将operation放到一个NSOperationQueue中,才会异步执行操作

NSBlockOperation

创建NSBlockOperation对象    + (id)blockOperationWithBlock:(void (^)(void))block;

通过addExecutionBlock:方法添加更多的操作    - (void)addExecutionBlock:(void (^)(void))block;

用法:

NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^(){

NSLog(@"执行了一个同步操作");

}];

[operation addExecutionBlock:^() {  //异步操作 

NSLog(@"执行了第2个新的操作,线程:%@", [NSThread currentThread]); }];

[operation addExecutionBlock:^() {  //异步操作 

NSLog(@"执行了第3个新的操作,线程:%@", [NSThread currentThread]); }];

[operation start];// 开始执行任务

注意:一般情况下,如果一个NSBlockOperation对象封装了多个任务。那么除第一个任务外,其他的任务会在新线程(子线程)中执行。即,NSBlockOperation是否开启新线程取决于任务的个数,任务的个数多,会自动开启新线程。但是第一个被执行的任务是同步执行,除第一个任务外,其他任务是异步执行的。

NSOperationQueue

NSOperation可以调用start方法来执行任务,但默认是同步执行的,如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作

添加操作到NSOperationQueue中

- (void)addOperation:(NSOperation *)op;

- (void)addOperationWithBlock:(void (^)(void))block;

NSOperation的completionBlock属性

如果想在操作执行完毕之后,还希望做一些其他的事情,可以通过completionBlock实现,并且永远是等待操作所有任务执行完毕最后被调用。

同步执行

NSBlockOperation *blkop = [NSBlockOperation blockOperationWithBlock:^{

[NSThread sleepForTimeInterval:3];

NSLog(@"执行%@",[NSThread currentThread]); }];

blkop.completionBlock = ^{ NSLog(@"完成"); };

[blkop start];

异步执行

NSBlockOperation *blkop = [NSBlockOperation blockOperationWithBlock:^{

[NSThread sleepForTimeInterval:4];

NSLog(@"执行%@",[NSThread currentThread]);  }];

blkop.completionBlock = ^{ NSLog(@"完成"); };

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[queue addOperation:blkop];

//如果一个操作是被加到操作队列中,然后才设置completionBlock,这样是可以的

总结:如果操作是通过调用start方法触发的,那么completionBlock必须要在start之前设置。如果操作是通过加入操作队列被触发的,那么completionBlock可以在操作添加到操作队列之后设置,只要保证此时操作没有被执行即可。

最大并发数  同时执行的任务数

最大并发数的相关方法

- (NSInteger)maxConcurrentOperationCount;

- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 设置最大并发操作数 // queue.maxConcurrentOperationCount = 5;

 queue.maxConcurrentOperationCount = 1; // 就变成了串行队列

 

 

NSOperation添加Dependency 

操作B依赖于操作A,所以一定要等操作A执行完毕才能执行操作B。执行顺序,不取决于添加到队列的先后顺序,而是取决于依赖关系(注:maxConcurrentOperationCount = 1除外,因为maxConcurrentOperationCount = 1时,操作队列为串行队列,如果没有给操作添加依赖,此时操作的执行顺序取决于操作添加到队列中的先后顺序。即便如此,maxConcurrentOperationCount = 1时,队列中的操作也并不一定在同一个线程中执行)

[operationB addDependency:operationA]; // 操作B依赖于操作A

如果操作设置了依赖,也给队列设置了maxConcurrentOperationCount = 1。那么操作被执行的顺序取决于依赖。即,依赖的优先级较高。

NSBlockOperation *blkop1 = [NSBlockOperation blockOperationWithBlock:^{

NSLog(@"执行1 %@",[NSThread currentThread]); }];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

queue.maxConcurrentOperationCount = 1;

NSBlockOperation *blkop2 = [NSBlockOperation blockOperationWithBlock:^{

NSLog(@"执行2 %@",[NSThread currentThread]); }];

[blkop1 addDependency:blkop2];//blkop1依赖于blkop2

[queue addOperation:blkop1];

[queue addOperation:blkop2];

注意:一定要在操作添加到队列之前设置操作之间的依赖,否则操作已经添加到队列中在设置依赖,依赖不会生效。依赖关系不局限于相同queue中的NSOperation对象,NSOperation对象会管理自己的依赖, 因此不同的操作队列之间的操作也可以设置依赖

队列的取消、暂停、恢复 

取消队列的所有操作

- (void)cancelAllOperations;//取消所有操作

提示:也可以调用NSOperation的- (void)cancel方法取消单个操作

暂停和恢复队列

- (void)setSuspended:(BOOL)b; // YES代表暂停队列,NO代表恢复队列

- (BOOL)isSuspended;

 

 

转载于:https://my.oschina.net/huangyn/blog/868764

你可能感兴趣的文章
IDDD 实现领域驱动设计-理解领域和子域
查看>>
Python标准库之urllib,urllib2自定义Opener
查看>>
jquery 自动完成 Autocomplete插件汇总
查看>>
jquery表单选择器
查看>>
日志插件 log4net 的使用
查看>>
小程序一:小程序的框架
查看>>
使用delphi 开发多层应用(八)客户端更新数据到kbmMW服务器
查看>>
HDU_3062 Party (2-SAT)
查看>>
dynamic_shift_reg SRL16E
查看>>
尝试用微博记录 SQL Server 2012开发者训练营笔记
查看>>
.Net中的5种事务总结
查看>>
为什么 Git 比 SVN 好
查看>>
关于Qt的MVC模型思想(转载)
查看>>
Vagrant支持Amazon AWS和Rackspace
查看>>
JNDI全攻略(二)(转)
查看>>
POJ1463:Strategic game(树形DP)
查看>>
SPOJ LCS(Longest Common Substring-后缀自动机-结点的Parent包含关系)
查看>>
Tuning 05 Sizing other SGA Structure
查看>>
用 Qt Creator 开发非 Qt 的 C/C++ 程序
查看>>
Android-Cannot merge new index 66195 into a non-jumbo instruction的解决的方法
查看>>