多线程之3-OperationQueue

2021-11-23  本文已影响0人  栋柠柒

Operation基于GCD封装, 完全面向对象. 对应于GCD, Operation也有任务和队列的概念, 只不过在Operation中任务(block)被称为操作(operation).
Operation支持以下关键功能:

1.操作之间添加依赖
2.使用KVO监听操作的执行状态
3.对操作进行优先级排序
4.取消操作

Operation是一个抽象类, 代表一个任务. 通常我们使用它的子类NSInvocationOperation或NSBlockOperation来编写任务代码. 当然也可以直接使用Operation, 不过需要重写main方法, 在main里面编写任务代码.

1.创建方式

2.执行方式

3.同步异步

Operation 没有 GCD 中的sync 和 async 方法。
苹果文档
如果计划手动执行操作对象,而不是将其添加到队列中,则可以将操作设计为以同步或异步方式执行。默认情况下,操作对象是同步的。当start()直接从代码中调用同步操作的方法时,该操作将在当前线程中立即执行。
默认情况下,操作对象以同步方式执行-也就是说,它们在调用其start方法的线程中执行其任务。
为了获得最佳性能,您应该将操作设计为尽可能异步,使应用程序在执行操作时可以自由地做其他工作。

4.队列(OperationQueue)

队列 (Operation Queue)有两种: 主队列和非主队列 (自定义队列).

添加操作(任务)到队列有四种方式:

5.串行并行

主队列是串行队列. 自定义队列默认是并发队列, 但可通多设置最大并发数(maxConcurrentOperationCount)来控制队列是串行还是并发.

maxConcurrentOperationCount

-1, 默认值, 并发队列;
=0, 不执行任何操作;
=1, 串行队列;
<0, 除-1默认值外, 其他负值均报错;
>1, 并发队列, 如果数值过大, 最终并发数由系统决定.

6.基本用法

1.不使用 OperationQueue
// block operation
let blockOperation = BlockOperation {
            for _ in 0...3 {
                print("blockOperation:\(Thread.current)")
            }
        }
        blockOperation.start()
//Operation
class CustomOperation: Operation {
    override func main() {
        print("\(#function), thread:\(Thread.current)")
    }
}

在自定义Operation中, 调用start方法后, 系统会执行多项安全检查, 最终会调用main方法.

2.使用 OperationQueue
let operationQueue = OperationQueue() // 默认并发执行
        let blockOperation = BlockOperation {
            for _ in 0...3 {
                print("blockOperation:\(Thread.current)")
            }
        }
        let blockOperationItem = BlockOperation {
            for _ in 0...3 {
                print("blockOperationItem:\(Thread.current)")
            }
        }
        operationQueue.addOperation(blockOperation)
        operationQueue.addOperation(blockOperationItem)
blockOperationItem:<NSThread: 0x600001d8e400>{number = 3, name = (null)}
blockOperation:<NSThread: 0x600001d98080>{number = 6, name = (null)}
blockOperation:<NSThread: 0x600001d98080>{number = 6, name = (null)}
blockOperationItem:<NSThread: 0x600001d8e400>{number = 3, name = (null)}
blockOperation:<NSThread: 0x600001d98080>{number = 6, name = (null)}
blockOperationItem:<NSThread: 0x600001d8e400>{number = 3, name = (null)}
blockOperation:<NSThread: 0x600001d98080>{number = 6, name = (null)}
blockOperationItem:<NSThread: 0x600001d8e400>{number = 3, name = (null)}
设置最大并发数
let operationQueue = OperationQueue() // 默认并发执行
        operationQueue.maxConcurrentOperationCount = 1
        let blockOperation = BlockOperation {
            for _ in 0...3 {
                print("blockOperation:\(Thread.current)")
            }
        }
        let blockOperationItem = BlockOperation {
            for _ in 0...3 {
                print("blockOperationItem:\(Thread.current)")
            }
        }
        operationQueue.addOperation(blockOperation)
        operationQueue.addOperation(blockOperationItem)
blockOperation:<NSThread: 0x6000021b4a00>{number = 3, name = (null)}
blockOperation:<NSThread: 0x6000021b4a00>{number = 3, name = (null)}
blockOperation:<NSThread: 0x6000021b4a00>{number = 3, name = (null)}
blockOperation:<NSThread: 0x6000021b4a00>{number = 3, name = (null)}
blockOperationItem:<NSThread: 0x6000021faac0>{number = 4, name = (null)}
blockOperationItem:<NSThread: 0x6000021faac0>{number = 4, name = (null)}
blockOperationItem:<NSThread: 0x6000021faac0>{number = 4, name = (null)}
blockOperationItem:<NSThread: 0x6000021faac0>{number = 4, name = (null)}
7.添加依赖

addDependency

let operationQueue = OperationQueue() // 默认并发执行
        operationQueue.maxConcurrentOperationCount = 1
        let blockOperation = BlockOperation {
            for _ in 0...3 {
                print("blockOperation:\(Thread.current)")
            }
        }
        let blockOperationItem = BlockOperation {
            for _ in 0...3 {
                print("blockOperationItem:\(Thread.current)")
            }
        }
        let blockOperationItem2 = BlockOperation {
            print("blockOperationItem2:\(Thread.current)")
        }
        blockOperationItem2.addDependency(blockOperationItem)
        operationQueue.addOperation(blockOperation)
        operationQueue.addOperation(blockOperationItem)
        operationQueue.addOperation(blockOperationItem2)
8.设置优先级
public enum QueuePriority : Int {

        case veryLow = -8

        case low = -4

        case normal = 0

        case high = 4

        case veryHigh = 8
    }
let operationQueue = OperationQueue() // 默认并发执行
        operationQueue.maxConcurrentOperationCount = 2
        let blockOperation = BlockOperation {
            for _ in 0...3 {
                print("blockOperation:\(Thread.current)")
            }
        }
        let blockOperationItem = BlockOperation {
            for _ in 0...3 {
                print("blockOperationItem:\(Thread.current)")
            }
        }
        let blockOperationItem2 = BlockOperation {
            print("blockOperationItem2:\(Thread.current)")
        }
        blockOperationItem2.addDependency(blockOperationItem)
        blockOperationItem.queuePriority = .veryHigh
        blockOperation.queuePriority = .low
        operationQueue.addOperation(blockOperation)
        operationQueue.addOperation(blockOperationItem)
        operationQueue.addOperation(blockOperationItem2)
blockOperationItem:<NSThread: 0x6000032979c0>{number = 6, name = (null)}
blockOperation:<NSThread: 0x600003298100>{number = 4, name = (null)}
blockOperation:<NSThread: 0x600003298100>{number = 4, name = (null)}
blockOperation:<NSThread: 0x600003298100>{number = 4, name = (null)}
blockOperation:<NSThread: 0x600003298100>{number = 4, name = (null)}
blockOperationItem:<NSThread: 0x6000032979c0>{number = 6, name = (null)}
blockOperationItem:<NSThread: 0x6000032979c0>{number = 6, name = (null)}
blockOperationItem:<NSThread: 0x6000032979c0>{number = 6, name = (null)}
blockOperationItem2:<NSThread: 0x6000032979c0>{number = 6, name = (null)}
9. 通过addExecutionBlock方法添加block操作
let operationQueue = OperationQueue() // 默认并发执行
        operationQueue.maxConcurrentOperationCount = 2
        let blockOperation = BlockOperation {
            for _ in 0...3 {
                print("blockOperation:\(Thread.current)")
            }
        }
        let blockOperationItem = BlockOperation {
            for _ in 0...3 {
                print("blockOperationItem:\(Thread.current)")
            }
        }
        blockOperationItem.addExecutionBlock {
            for _ in 0...2 {
                print("blockOperationItem addExecutionBlock:\(Thread.current)")
            }
        }
        operationQueue.addOperation(blockOperation)
        operationQueue.addOperation(blockOperationItem)
blockOperation:<NSThread: 0x6000028be9c0>{number = 7, name = (null)}
blockOperationItem:<NSThread: 0x6000028be700>{number = 5, name = (null)}
blockOperationItem addExecutionBlock:<NSThread: 0x6000028c4100>{number = 6, name = (null)}
blockOperationItem addExecutionBlock:<NSThread: 0x6000028c4100>{number = 6, name = (null)}
blockOperationItem addExecutionBlock:<NSThread: 0x6000028c4100>{number = 6, name = (null)}
blockOperationItem:<NSThread: 0x6000028be700>{number = 5, name = (null)}
blockOperation:<NSThread: 0x6000028be9c0>{number = 7, name = (null)}
blockOperationItem:<NSThread: 0x6000028be700>{number = 5, name = (null)}
blockOperation:<NSThread: 0x6000028be9c0>{number = 7, name = (null)}
blockOperationItem:<NSThread: 0x6000028be700>{number = 5, name = (null)}
blockOperation:<NSThread: 0x6000028be9c0>{number = 7, name = (null)}

可以看到,通过addExecutionBlock 方法添加的代码块是在blockOperationItem开始执行之后,另外开辟了一条新线程执行的。

上一篇下一篇

猜你喜欢

热点阅读