iOS 之 多线程(二)

1,009 阅读2分钟

GCD

特性

  • 创建管理Queue
  • 提交Job
  • Dispatch Group
  • 管理 Dispatch Object
  • 信号量 Semaphore
  • 队列屏障 Barrier
  • Dispatch Source
  • Queue Context 数据
  • Dispatch IO Channel
  • Dispatch Data 对象

GCD队列

  • 主队列 : 任务在主线程执行

  • 并队列列 : 任务会以先进先出的顺序入列和出列, 但是因为多个任务可以并行执行,所以完成的顺序不一定的

  • 串行队列 : 任务会一先进先出的属性出列和入列,但是同一时刻只会执行一个任务

  • API

    • Dispatch.main
    • Dispatch.global
    • DispatchQueue(label:, qos:, attributes:, autorealeaseFrequency:, target:, )
    • queue.label;
    • setTarget(queue: DispatchQueue?)

image.png

  • 最终的目标队列都是主队列和全局队列
  • 如果把一个并行队列的目标队列设置为一个串行队列,那么并行队列将不再并行
  • 如果对歌队列的目标队列都设置为同一个串行队列,那么这多个队列连同目标队列里的任务都将串行执行
  • 如果设置目标队列形成环了,结果是不可预期的
  • 如果在一个队列正在执行任务的时候更换目标队列,结果也是不可预期的

GCD 基本操作

  • 同步和异步
  • sync
    • 提交任务到当前队列,并且知道任务执行完成,当前队列才会返回
  • async
  • asyncAfter
    • 调度一个任务多久之后执行,但是不用等任务执行完当前队列就会返回
let queue = DispatchQueue(label: "myqyeue", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)

queue.sync {
    print("in queue sync")
}
queue.async {
    sleep(1)
    print("in queue async")
}

queue.asyncAfter(deadline: .now() + 1) {
    print("in asyncAfter")
}
print("after invoke queue")

GCD 高级特性

  • DispatchGroup

image.png

let workingGroup = DispatchGroup()
let workingQueue = DispatchQueue(label: "request_queue")

workingGroup.enter()
workingQueue.async {
    Thread.sleep(forTimeInterval: 1)
    print("接口A 数据请求完成")
    workingGroup.leave()
}

workingGroup.enter()
workingQueue.async {
    Thread.sleep(forTimeInterval: 1)
    print("接口B 数据请求完成")
    workingGroup.leave()
}

print("我是最开始执行的,异步操作里的打印后执行")
workingGroup.wait()
print("接口A、B的数据请求完成,开始合并两个接口的数据")
  • Dispatch_notify
let workingGroup = DispatchGroup()
let workingQueue = DispatchQueue(label: "request_queue")

workingGroup.enter()
workingQueue.async {
    Thread.sleep(forTimeInterval: 1)
    print("接口A 数据请求完成")
    workingGroup.leave()
}

workingGroup.enter()
workingQueue.async {
    Thread.sleep(forTimeInterval: 1)
    print("接口B 数据请求完成")
    workingGroup.leave()
}

print("我是最开始执行的,异步操作里的打印后执行")
workingGroup.notify(queue: workingQueue) {
    print("接口A、B的数据请求完成,开始合并两个接口的数据")
}
print("验证不阻塞")
  • DispatchSource
    • dispatch source 是监听某些类型事件的对象,当这些事件发生时,它将自动一个task放入一个dispatch queue的执行例程中
    • 有很多事件
let queue = DispatchQueue(label: "request_queue")
var seconds = 10
let timer = DispatchSource.makeTimerSource(flags: [], queue: queue)
timer.schedule(deadline: .now(), repeating: 1.0)
timer.setEventHandler {
    seconds -= 1
    if seconds < 0 {
        timer.cancel()
    }else{
        print(seconds)
    }
}
timer.resume()