NSOperation的高级功能

"最大并发数"
#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) NSOperationQueue *queue;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.queue = [[NSOperationQueue alloc] init];
    // 设置队列最大并发数 : 决定的是队列最多可以同时调度执行的任务数.并不是线程数!
    self.queue.maxConcurrentOperationCount = 2.0;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self OPDemo];
}

- (void)OPDemo
{
    for (NSInteger i = 0; i < 10; i++) {

        [self.queue addOperationWithBlock:^{

            // 这行代码没有实际意义,仅仅是为了放大队列最大并发数的效果
            [NSThread sleepForTimeInterval:1.0];

            NSLog(@"%zd %@",i,[NSThread currentThread]);
        }];
    }
}

"队列的暂停/继续/取消全部"
#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) NSOperationQueue *queue;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.queue = [[NSOperationQueue alloc] init];
    // 设置队列最大并发数 : 决定的是队列最多可以同时调度执行的任务数.并不是线程数!
    self.queue.maxConcurrentOperationCount = 2.0;
}



#pragma mark - 暂停队列调度任务
/*
 1.正在执行的操作是无法暂停的
 2.队列里面的操作一旦执行完,就会从队列移除
 3.operationCount : 保存的是队列里面还没有执行完的操作(没有被调度,调度了还没有执行完)
 */
- (IBAction)Stop:(id)sender
{
    // 使队列暂停调度任务执行
    self.queue.suspended = YES;

    NSLog(@"暂停 %tu",self.queue.operationCount);
}


#pragma mark - 使队列继续调度任务执行
- (IBAction)GoOn:(id)sender
{
    // 使队列继续调度任务执行
    self.queue.suspended = NO;
    NSLog(@"继续 %tu",self.queue.operationCount);
}

#pragma mark - 取消队列里面的全部
/*
 1.正在执行的操作无法被取消;
 2.提示 : 如果非要取消正在执行的操作,需要自定义NSOperation
 3.提示 : 一旦取消了队列里面的操作,队列就会把相应的操作从队列里面移除
 4.提示 : cancelAllOperations会有一定的延迟;
 */
- (IBAction)cancleAll:(id)sender
{
    [self.queue cancelAllOperations];

    NSLog(@"取消全部 %tu",self.queue.operationCount);
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self OPDemo];
}

- (void)OPDemo
{
    for (NSInteger i = 0; i < 20; i++) {

        [self.queue addOperationWithBlock:^{

            // 这行代码没有实际意义,仅仅是为了放大队列最大并发数的效果
            [NSThread sleepForTimeInterval:1.0];

            NSLog(@"%zd %@",i,[NSThread currentThread]);
        }];
    }
}

"操作间的依赖"
#import "ViewController.h"

@interface ViewController ()

@end

/// 需求 : 登录 --> 付费 --> 下载 --> 通知用户

@implementation ViewController {

    /// 全局队列
    NSOperationQueue *_queue;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    _queue = [[NSOperationQueue alloc] init];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self OPDemo];
}

- (void)OPDemo
{
    // 登录
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"登录 %@",[NSThread currentThread]);
    }];

    // 付费
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"付费 %@",[NSThread currentThread]);
    }];

    // 下载
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"下载 %@",[NSThread currentThread]);
    }];

    // 通知用户
    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"通知用户 %@",[NSThread currentThread]);
    }];

    /*
     建立操作间依赖关系小结
     1.不能建立循环依赖,如果建立循环依赖,会出现死锁
     2.可以跨队列建立依赖关系
     3.一定要先建立好依赖关系,在把操作添加到队列
     */

    // 建立操作间依赖关系
    [op2 addDependency:op1]; // 付费依赖于登录
    [op3 addDependency:op2]; // 下载依赖于付费
    [op4 addDependency:op3]; // 通知用户依赖于下载

    // 建立循环依赖
//    [op1 addDependency:op4];

    // 批量把操作添加到队列
    // waitUntilFinished : 是否等待前面的异步任务执行完,在执行后面的代码
    [_queue addOperations:@[op1,op2,op3] waitUntilFinished:NO];

    // 把通知用户添加到主队列
    // 提示 : 一个操作不能被同时添加到两个队列
    [[NSOperationQueue mainQueue] addOperation:op4];

    NSLog(@"后面的代码");
}

"监听操作是否执行完毕/设置操作的服务质量"
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController {
    NSOperationQueue *_queue;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    _queue = [[NSOperationQueue alloc] init];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self OPDemo];
}

- (void)OPDemo
{
    // 操作1
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{

        for (NSInteger i = 0; i < 10; i++) {
            NSLog(@"op1 %zd %@",i,[NSThread currentThread]);
        }
    }];
    // 设置操作的服务质量 : 决定的是队列里面的操作有更多的机会呗调度执行
    op1.qualityOfService = NSQualityOfServiceUserInteractive;

    // 设置监听操作执行结束 : 异步监听 / 在子线程监听
    /*
    op1.completionBlock = ^{
        NSLog(@"op1确定执行完了吗? %@",[NSThread currentThread]);
    };
     */

    // 提示 : 如果给对象的block属性赋值的快捷方式
    [op1 setCompletionBlock:^{
        NSLog(@"op1确定执行完了吗? %@",[NSThread currentThread]);
    }];

    // 操作1
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{

        for (NSInteger i = 0; i < 10; i++) {
            NSLog(@"op2 %zd %@",i,[NSThread currentThread]);
        }
    }];
    // 设置操作的服务质量
    op2.qualityOfService = NSQualityOfServiceBackground;

    [_queue addOperations:@[op1,op2] waitUntilFinished:NO];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zok93

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值