NSOperation用法

2021-09-08  本文已影响0人  liang1030

一,NSOperation简介

1,NSOperation是一个抽象类,需要使用子类实现具体的功能。
2,NSOperation是基于GCD的面相对象封装。
3,不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上。

二,NSOperation优势

1,可以设置最大并发数

2,可以设置线程间的依赖关系

3,可以设置优先级

4,可以暂停、继续、取消

5,可以监听属性的变化

三,两个核心概念

1,Operation(操作):NSInvocationOperation,NSBlockOperation,自定义子类
2,queue(队列):NSOperationQueue

四,NSOperation使用:

NSBlockOperation

1,简介

NSBlockOperation类是NSOperation的一个具体子类,用于管理一个或多个块的并发执行。您可以使用这个对象一次执行多个块,而不必为每个块创建单独的操作对象。当执行多个块时,只有当所有块都已完成执行时,才认为操作本身已完成。

添加到block operation的块将以默认优先级分派到适当的工作队列。块本身不应该对其执行环境的配置做出任何假设。

2,方法

//创建并返回一个NSBlockOperation对象,并将指定的块添加到它。
blockOperationWithBlock:

//将指定的块添加到接收者要执行的块列表中。
addExecutionBlock:

3,属性

//与接收器相关联的块
executionBlocks

4,使用方法

blockOperationWithBlock方法:

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

[op1 start];
[op2 start];
[op3 start];

始终打印:

2021-09-08 13:41:05.836798+0800 OperationTest[35466:17354403] ---1--<NSThread: 0x2807f0900>{number = 1, name = main}---
2021-09-08 13:41:05.836886+0800 OperationTest[35466:17354403] ---2--<NSThread: 0x2807f0900>{number = 1, name = main}---
2021-09-08 13:41:05.836927+0800 OperationTest[35466:17354403] ---3--<NSThread: 0x2807f0900>{number = 1, name = main}---

解析:

使用NSBlockOperation类方法blockOperationWithBlock创建的多个任务,会按照调用实例方法start的顺序,在当前线程同步执行。

addExecutionBlock方法:

NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"---1--%@---", [NSThread currentThread]);
}];
//NSBlockOperation *op1 = [[NSBlockOperation alloc] init];
[op1 addExecutionBlock:^{
    NSLog(@"---1.1--%@---", [NSThread currentThread]);
}];
[op1 addExecutionBlock:^{
    NSLog(@"---1.2--%@---", [NSThread currentThread]);
}];
[op1 addExecutionBlock:^{
    NSLog(@"---1.3--%@---", [NSThread currentThread]);
}];
[op1 addExecutionBlock:^{
    NSLog(@"---1.4--%@---", [NSThread currentThread]);
}];
    
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"---2--%@---", [NSThread currentThread]);
}];
//NSBlockOperation *op2 = [[NSBlockOperation alloc] init];
[op2 addExecutionBlock:^{
    NSLog(@"---2.1--%@---", [NSThread currentThread]);
}];
[op2 addExecutionBlock:^{
    NSLog(@"---2.2--%@---", [NSThread currentThread]);
}];
    
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"---3--%@---", [NSThread currentThread]);
}];
//NSBlockOperation *op3 = [[NSBlockOperation alloc] init];
[op3 addExecutionBlock:^{
    NSLog(@"---3.1--%@---", [NSThread currentThread]);
}];
[op3 addExecutionBlock:^{
    NSLog(@"---3.2--%@---", [NSThread currentThread]);
}];
    
[op1 start];
[op2 start];
[op3 start];

打印:

第一次打印
2021-09-08 14:00:05.085719+0800 OperationTest[35494:17363182] ---1--<NSThread: 0x281074900>{number = 1, name = main}---
2021-09-08 14:00:05.085730+0800 OperationTest[35494:17363382] ---1.1--<NSThread: 0x28103c2c0>{number = 5, name = (null)}---
2021-09-08 14:00:05.085802+0800 OperationTest[35494:17363182] ---1.3--<NSThread: 0x281074900>{number = 1, name = main}---
2021-09-08 14:00:05.085803+0800 OperationTest[35494:17363382] ---1.2--<NSThread: 0x28103c2c0>{number = 5, name = (null)}---
2021-09-08 14:00:05.085850+0800 OperationTest[35494:17363380] ---1.4--<NSThread: 0x28103d940>{number = 3, name = (null)}---
2021-09-08 14:00:05.085901+0800 OperationTest[35494:17363182] ---2--<NSThread: 0x281074900>{number = 1, name = main}---
2021-09-08 14:00:05.085912+0800 OperationTest[35494:17363380] ---2.1--<NSThread: 0x28103d940>{number = 3, name = (null)}---
2021-09-08 14:00:05.085955+0800 OperationTest[35494:17363383] ---2.2--<NSThread: 0x281038280>{number = 7, name = (null)}---
2021-09-08 14:00:05.086049+0800 OperationTest[35494:17363182] ---3--<NSThread: 0x281074900>{number = 1, name = main}---
2021-09-08 14:00:05.086052+0800 OperationTest[35494:17363383] ---3.1--<NSThread: 0x281038280>{number = 7, name = (null)}---
2021-09-08 14:00:05.086082+0800 OperationTest[35494:17363380] ---3.2--<NSThread: 0x28103d940>{number = 3, name = (null)}---

第n次打印
2021-09-08 14:05:55.583552+0800 OperationTest[35504:17365839] ---1.1--<NSThread: 0x28350cc40>{number = 6, name = (null)}---
2021-09-08 14:05:55.583598+0800 OperationTest[35504:17365837] ---1.2--<NSThread: 0x28350cf40>{number = 5, name = (null)}---
2021-09-08 14:05:55.583545+0800 OperationTest[35504:17365827] ---1--<NSThread: 0x28354c900>{number = 1, name = main}---
2021-09-08 14:05:55.583660+0800 OperationTest[35504:17365842] ---1.4--<NSThread: 0x28350d100>{number = 3, name = (null)}---
2021-09-08 14:05:55.583671+0800 OperationTest[35504:17365838] ---1.3--<NSThread: 0x283500240>{number = 7, name = (null)}---
2021-09-08 14:05:55.583723+0800 OperationTest[35504:17365827] ---2--<NSThread: 0x28354c900>{number = 1, name = main}---
2021-09-08 14:05:55.583734+0800 OperationTest[35504:17365838] ---2.1--<NSThread: 0x283500240>{number = 7, name = (null)}---
2021-09-08 14:05:55.583759+0800 OperationTest[35504:17365827] ---2.2--<NSThread: 0x28354c900>{number = 1, name = main}---
2021-09-08 14:05:55.583897+0800 OperationTest[35504:17365827] ---3--<NSThread: 0x28354c900>{number = 1, name = main}---
2021-09-08 14:05:55.583916+0800 OperationTest[35504:17365838] ---3.1--<NSThread: 0x283500240>{number = 7, name = (null)}---
2021-09-08 14:05:55.583933+0800 OperationTest[35504:17365842] ---3.2--<NSThread: 0x28350d100>{number = 3, name = (null)}---

解析:

1,使用方法blockOperationWithBlock添加的任务都在当前线程中执行。
2,使用方法addExecutionBlock追加的任务可能在当前线程中执行,也可能在新开的线程中执行。
3,单个NSBlockOperation中有多个任务的话会开启新线程并发执行。
4,多个NSBlockOperation会按照调用start方法的顺序同步执行。(op1中任务执行完,才开始执行op2的任务,以此类推)。

NSInvocationOperation

1,简介

NSInvocationOperation类是NSOperation的一个具体子类,管理指定为调用的单个封装任务的执行的操作。可以初始化一个调用指定对象上的选择器的操作。NSInvocationOperation实现了一个非并发操作。

2,方法

//返回使用指定目标和选择器初始化的NSInvocationOperation对象。
initWithTarget:selector:object:

//返回一个由指定的调用对象初始化的NSInvocationOperation对象。
initWithInvocation:

3,使用方法

NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operation1:) object:@"first"];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operation2:) object:@"second"];
NSInvocationOperation *op3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operation3:) object:@"third"];
    
[op1 start];
[op2 start];
[op3 start];

- (void)operation1:(id)obj {
    NSLog(@"---1--%@--%@---", obj, [NSThread currentThread]);
}

- (void)operation2:(id)obj {
    NSLog(@"---2--%@--%@---", obj, [NSThread currentThread]);
}

- (void)operation3:(id)obj {
    NSLog(@"---3--%@--%@---", obj, [NSThread currentThread]);
}

打印:

2021-09-08 14:41:41.399288+0800 OperationTest[35516:17375314] ---1--first--<NSThread: 0x281c78900>{number = 1, name = main}---
2021-09-08 14:41:41.399381+0800 OperationTest[35516:17375314] ---2--second--<NSThread: 0x281c78900>{number = 1, name = main}---
2021-09-08 14:41:41.399427+0800 OperationTest[35516:17375314] ---3--third--<NSThread: 0x281c78900>{number = 1, name = main}---

解析:

NSInvocationOperation不会开启新线程,默认在当前线程(执行该方法的线程)中同步执行。

上一篇下一篇

猜你喜欢

热点阅读