swiftSwift学习小知识点

Swift4.0 - GCD

2018-01-20  本文已影响5845人  SealShile

简介

Grand Central Dispatch (GCD) 是Apple开发的一个多核编程的较新的解决方法。它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。

众所周知,GCD, NSOperationQueue, NSThread, pthread是iOS中多线程的几种处理方式,Swift3之前GCD仍是面向过程的写法,所以需要封装一层再使用。Swift3苹果打成Dispatch这个module.你可以通过import进行导入再使用。Swift4,直接使用。

特性

GCD可用于多核的并行运算
GCD会自动利用更多的CPU内核(比如双核、四核)
GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)

用法

  1. 异步执行回主线程写法
DispatchQueue.global().async {
            print("async do something\(Thread.current)")
            DispatchQueue.main.async {
                print("come back to main thread\(Thread.current)")
            }
        }
  1. QoS
    之前接触过Quality of Service还是在VoIP,通过QoS来标注每个通信的priority,所以这边其实是把
DISPATCH_QUEUE_PRIORITY_HIGHT
DISPATCH_QUEUE_PRIORITY_DEFAULT
DISPATCH_QUEUE_PRIORITY_LOW
DISPATCH_QUEUE_PRIORITY_BACKGROUND

转换成了

User Interactive 和用户交互相关,比如动画等等优先级最高。比如用户连续拖拽的计算

User Initiated 需要立刻的结果,比如push一个ViewController之前的数据计算

Utility 可以执行很长时间,再通知用户结果。比如下载一个文件,给用户下载进度

Background 用户不可见,比如在后台存储大量数据

在GCD中,指定QoS有以下两种方式
方式一,创建一个指定QoS的queue

let queue = DispatchQueue(label: "labelname", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit)

方式二,在提交block的时候,指定QoS

queue.async(group: nil, qos: .background, flags: .inheritQoS) {
            <#code#>
}

flags的参数有

public static let barrier: DispatchWorkItemFlags

public static let detached: DispatchWorkItemFlags

public static let assignCurrentContext: DispatchWorkItemFlags

public static let noQoS: DispatchWorkItemFlags

public static let inheritQoS: DispatchWorkItemFlags

public static let enforceQoS: DispatchWorkItemFlags

其中关于QoS的关系,可以通过flags参数设置。

  1. DispatchWorkItem
let dispatchWorkItem = DispatchWorkItem(qos: .default, flags: .barrier) {
    <#code#>
}
  1. after
let deadline = DispatchTime.now() + 5.0
        DispatchQueue.global().asyncAfter(deadline: deadline) {
            <#code#>
        }
  1. DispatchGroup

DispatchGroup用来管理一组任务的执行,然后监听任务都完成的事件。比如,多个网络请求同时发出去,等网络请求都完成后reload UI。

let group = DispatchGroup()
        group.enter()
        self.sendHTTPRequest1(params:[String: Any]) {
            print("request complete")
            group.leave()
        }
        group.enter()
        self.sendHTTPRequest1(params:[String: Any]) {
            print("request complete")
            group.leave()
        }
        group.notify(queue: DispatchQueue.main) {
            print("all requests come back")
        }
  1. Semaphore

Semaphore是保证线程安全的一种方式,而且继OSSpinLock不再安全后,Semaphore似乎成为了最快的加锁的方式。
如图


1513585102364922.png
let semaphore = DispatchSemaphore(value: 2)
let queue = DispatchQueue.global()

        queue.async {
            semaphore.wait()
            self.sendHTTPRequest1(params:[String: Any]) {
                print("request complete")
                semaphore.signal()
            }
        }
        queue.async {
            semaphore.wait()
            self.sendHTTPRequest2(params:[String: Any]) {
                print("request complete")
                semaphore.signal()
            }
        }
        queue.async {
            semaphore.wait()
            self.sendHTTPRequest3(params:[String: Any]) {
                print("request complete")
                semaphore.signal()
            }
        }
  1. Barrier

GCD里的Barrier和NSOperationQueue的dependency比较接近,C任务开始之前需要A任务完成,或者A和B任务完成。

let queue = DispatchQueue(label: "foo", attributes: .concurrent)
        queue.async {
            self.sendHTTPRequest1(params:[String: Any]) {
                print("A")
            }
        }
        queue.async {
            self.sendHTTPRequest2(params:[String: Any]) {
                print("B")
            }
        }
        queue.async(flags: .barrier) {
            self.sendHTTPRequest3(params:[String: Any]) {
                print("C")
            }
        }
上一篇下一篇

猜你喜欢

热点阅读