iOS-多线程-NSOperation

本文详细介绍了iOS多线程方案NSOperation及NSOperationQueue的使用方法,包括不同子类的实例创建与启动,队列的串行与并行控制,以及操作间的依赖关系。

一,什么是NSOpeation
NSOperation是苹果提供给我们的一套多线程解决方案。实际上NSOperation是基于GCD更高一层的封装,但是比GCD更简单易用、代码可读性也更高。


二,NSOperation&NSOperationQueue的基本使用
1,NSOperation
NSOperation是一个抽象类,并不能封装任务,我们只有使用他的子类来封装任务.有三钟方式来封装:

  • 使用子类NSInvocationOperation
  • 使用子类NSBlockOperation 定义继承NSOperation的子类,通过实现内部相应的方法来封装任务

  • NSInvocationOperation

    //1,创建NSInvoctionOperation
    NSInvocationOperation *invocation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run) object:nil];

    //2,调用start开始操作
    [invocation start];

    //没有使用NSOperation类时,并没有开启新的线程(在主线程执行)
  • NSBlockOperation
    //创建NSBlockOperation
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"执行任务-- %@",[NSThread currentThread]);    
    }];
   //start
    [blockOperation start];

    //使用NSBlockOperation,没有开启行的线程(在主线程执行)
  • NSBlockOperation的addExecutionBlock:
    //创建NSBlockOperation
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"执行任务1-- %@",[NSThread currentThread]);
    }];
    // 添加额外的任务(在子线程执行)
    [blockOperation addExecutionBlock:^{
        NSLog(@"2------%@", [NSThread currentThread]);
    }];
    [blockOperation addExecutionBlock:^{
        NSLog(@"3------%@", [NSThread currentThread]);
    }];
    [blockOperation addExecutionBlock:^{
        NSLog(@"4------%@", [NSThread currentThread]);
    }];
    [blockOperation start];
   //使用NSBlockOperation的addExecutionBlock:方法,会开启线程
  • 自定义继承NSOperation的子类

.h文件

import <Foundation/Foundation.h>

@interface GSOperation : NSOperation

@end

.m文件

#import "GSOperation.h"

@implementation GSOperation

//执行需要执行的任务
-(void)main{

    for (int i = 0; i < 9; ++i) {

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

}
@end

单独使用自定义子类的情况下,是在主线程执行操作,并没有开启新线程。

2,NSOperationQueue
NSOperationQueue一共有两种队列:主队列、其他队列,其他队列同时包含了串行、并发功能。

  • 主队列:
    凡是添加到主队列中的任务(NSOperation),都会放到主线程中执行
    NSOperationQueue *queue = [NSOperationQueue mainQueue];

  • 其他队列(非主队列)
    添加到这种队列中的任务(NSOperation),就会自动放到子线程中执行
    同时包含了:串行、并发功能
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

将任务加入到队列中
总共有两种方法:
1,NSOperationQueue的addOperation:方法,需要先创建任务,再将创建好的任务加入到创建好的队列中去

    // 1.创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    // 2. 创建操作
    // 创建NSInvocationOperation
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
    // 创建NSBlockOperation
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 2; ++i) {
            NSLog(@"1-----%@", [NSThread currentThread]);
        }
    }];

    // 3. 添加操作到队列中:addOperation:
    [queue addOperation:op1]; // [op1 start]
    [queue addOperation:op2]; // [op2 start]

总结:不管是NSInvocationOperation,还是NSBlockOperation,在添加到队列后都可以并发执行,

2,addOperationWithBlock:无需先创建任务,在block中添加任务,直接将任务block加入到队列中.

  // 1. 创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    // 2. 添加操作到队列中:addOperationWithBlock:
    [queue addOperationWithBlock:^{
        for (int i = 0; i < 2; ++i) {
            NSLog(@"-----%@", [NSThread currentThread]);
        }
    }];

总结:可以并行执行


三,控制串行执行和并行执行的关键
NSOperationQueue创建的其他队列同时具有串行、并发功能,关键操作在于maxConcurrentOperationCount:(最大并发数)这个参数中

  • 默认情况下maxConcurrentOperationCount为-1,表示不进行限制,默认为并发执行。
  • 当maxConcurrentOperationCount为1时,进行串行执行。
  • 当maxConcurrentOperationCount大于1时,进行并发执行,当然这个值不应超过系统限制,即使自己设置一个很大的值,系统也会自动调整。
    // 创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    // 设置最大并发操作数
    //    queue.maxConcurrentOperationCount = 2;
    queue.maxConcurrentOperationCount = 1; // 就变成了串行队列

    // 添加操作
    [queue addOperationWithBlock:^{
        NSLog(@"1-----%@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:0.01];
    }];
    [queue addOperationWithBlock:^{
        NSLog(@"2-----%@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:0.01];
    }];
    [queue addOperationWithBlock:^{
        NSLog(@"3-----%@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:0.01];
    }];
    [queue addOperationWithBlock:^{
        NSLog(@"4-----%@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:0.01];
    }];
    [queue addOperationWithBlock:^{
        NSLog(@"5-----%@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:0.01];
    }];

    [queue addOperationWithBlock:^{
        NSLog(@"6-----%@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:0.01];
    }];

总结:当最大并发数为1时,任务是按顺序串行执行的。当最大并发数为2时,任务是并发执行的。而且开启线程数量是由系统决定的,不需要我们来管理


四,操作依赖
A、B两个操作,其中A执行完操作,B才能执行操作,那么就需要让B依赖于A。具体如下:

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

    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1-----%@", [NSThread  currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2-----%@", [NSThread  currentThread]);
    }];

    [op2 addDependency:op1];    // 让op2 依赖于 op1,则先执行op1,在执行op2

    [queue addOperation:op1];
    [queue addOperation:op2];

执行结果是:op1先执行,op2后执行;


以上是学习后的一些总结,有什么错误的还请各位指点

乐播投屏是一款简单好用、功能强大的专业投屏软件,支持手机投屏电视、手机投电脑、电脑投电视等多种投屏方式。 多端兼容与跨网投屏:支持手机、平板、电脑等多种设备之间的自由组合投屏,且无需连接 WiFi,通过跨屏技术打破网络限制,扫一扫即可投屏。 广泛的应用支持:支持 10000+APP 投屏,包括综合视频、网盘与浏览器、美韩剧、斗鱼、虎牙等直播平台,还能将央视、湖南卫视等各大卫视的直播内容一键投屏。 高清流畅投屏体验:腾讯独家智能音画调校技术,支持 4K 高清画质、240Hz 超高帧率,低延迟不卡顿,能为用户提供更高清、流畅的视觉享受。 会议办公功能强大:拥有全球唯一的 “超级投屏空间”,扫码即投,无需安装。支持多人共享投屏、远程协作批注,PPT、Excel、视频等文件都能流畅展示,还具备企业级安全加密,保障会议资料不泄露。 多人互动功能:支持多人投屏,邀请好友加入投屏互动,远程也可加入。同时具备一屏多显、语音互动功能,支持多人连麦,实时语音交流。 文件支持全面:支持 PPT、PDF、Word、Excel 等办公文件,以及视频、图片等多种类型文件的投屏,还支持网盘直投,无需下载和转格式。 特色功能丰富:投屏时可同步录制投屏画面,部分版本还支持通过触控屏或电视端外接鼠标反控电脑,以及在投屏过程中用画笔实时标注等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值