DispatchWorkItem

3,081 阅读2分钟

DispatchQueue

使用DispatchQueue创建队列有两种方式:

第一种

let queue = DispatchQueue(label: "dow")
queue.async {
    print(Thread.current)
    for i in 0...3 {
        sleep(1)
        print(i)
    }
}
queue.async {
    print(Thread.current)
    for i in 0...3 {
        sleep(1)
        print(i)
    }
}

打印结果为:

<NSThread: 0x1c06607c0>{number = 3, name = (null)}
0
1
2
3
<NSThread: 0x1c06607c0>{number = 3, name = (null)}
0
1
2
3

所以这种默认创建队列的方式是串行队列。

第二种方式:

public convenience init(label: String, qos: DispatchQoS = default, attributes: DispatchQueue.Attributes = default, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency = default, target: DispatchQueue? = default)

可以设置attributes,串行队列为DispatchQueue.Attributes.init(rawValue: 0),并行队列为DispatchQueue.Attributes.concurrent

DispatchWorkItem

先定义一个DispatchWorkItem:

let workItem = DispatchWorkItem {
    for i in 0...3 {
        sleep(1)
        print(i)
    }
}

1.取消一个已经运行的DispatchWorkItem

DispatchQueue.global().async(execute: workItem)
workItem.cancel()

打印结果为0、1、2、3。说明DispatchWorkItem只要开始运行就无法取消。

2.取消一个未运行的DispatchWorkItem

workItem.cancel()
DispatchQueue.global().async(execute: workItem)
print(workItem.isCancelled)

打印结果为true任何信息。说明未开始运行的DispatchWorkItem被取消掉后,就不会再被运行。其属性isCancelled被制为true

3.DispatchWorkItem中的wait:

DispatchQueue.global().async(execute: workItem)
workItem.wait()
print("workEnd")

打印结果为:0、1、2、3、workEnd。所以,workItem会阻塞当前线程直到任务完成。

对于wait(timeout: DispatchTime)方法:

DispatchQueue.global().async(execute: workItem)
let timeoutResult = workItem.wait(timeout: .now() + 2)
switch timeoutResult {
case .success:
    print("success")
case .timedOut:
    print("timedOut")
}

打印结果为:0、defeat、1、2、3。方法会阻塞当前线程直到timeout,如果对应的workItem被调用且完成timeoutResultsuccess,否则为timedOut

4.DispatchWorkItem中的notify:

workItem.notify(queue: DispatchQueue.main) {
    print("workEnd")
}
DispatchQueue.global().async(execute: workItem)

打印结果为:0、1、2、3、workEnd。所以notify会在任务结束时执行block方法。

barrier

创建并行队列异步执行任务:

queue.async {
    sleep(3)
    print(1)
}
queue.async {
    sleep(2)
    print(2)
}
queue.async(flags: DispatchWorkItemFlags.barrier) {
    sleep(1)
    print(3)
}
queue.async {
    sleep(1)
    print(4)
}

打印结果为:

2
1
3
4

所以barrier所在队列之前所有任务完成执行barrier任务,执行完毕后再执行barrier后所有任务。