赞
踩
GCD(Grand Central Dispatch)是基于C语言开发的一套多线程开发机制,也是目前苹果官方推荐的多线程开发方法。相对于 NSThread 和 NSOperation,GCD抽象层次最高,使用起来也最简单,只是它基于C语言开发,并不像NSOperation是面向对象的开发,而是完全面向过程的。这种机制相比较于前面两种多线程开发方式最显著的优点就是它对于多核运算更加有效。
GCD 中使用队列管理任务, 队列是一种 FIFO 的数据结构。
两个特殊队列:
说完队列,相应的,任务除了管理,还得执行。在GCD中并不能直接开辟线程执行任务,所以在任务加入队列之后,GCD给出了两种执行方式:
一般多任务,耗时操作选用 并行 + 异步;单任务,UI 刷新选用 主队列 + 异步。
- // 主线程同步操作,引起死锁
- dispatch_sync(dispatch_get_main_queue(), ^{
- print(“”);
- });
创建队列
- //主队列
- let mainQueue = DispatchQueue.main
- //全局队列
- let globalQueue = DispatchQueue.global()
- //串行队列,不指定属性时默认
- let serialQueue = DispatchQueue(label: "com.label.serial")
- //并发队列
- let concurrentQueue = DispatchQueue(label: "com.label.concurrent", attributes: .concurrent)
-
-
- /// 自定义并发队列
- ///
- /// - Parameters:
- /// - label: 标识符
- /// - qos: 优先级(quality of service)
- /// - attributes: 队列属性(类型)
- /// - autoreleaseFrequency: 自动释放频率
- /// - target:
- let queueInactive = DispatchQueue.init(label: "com.queue.concurent", qos: DispatchQoS.default, attributes: [.concurrent, .initiallyInactive], autoreleaseFrequency: .workItem, target: nil)
- //触发后才执行
- queueInactive.async {
- print("++++++\(Thread.current)")
- }
- //手动触发
- queueInactive.activate()
分组队列
- func groupAction(_ sender: UIButton) {
- //DispatchGroup用来管理一组任务的执行,然后监听任务全部完成。比如,多个网络请求同时发出去,等网络请求都完成后reload UI。
-
- let group = DispatchGroup()
- let concuQueue = DispatchQueue(label: "concu", qos: .default)
- let itemOne = DispatchWorkItem {
- print("====\(Thread.current)====")
- }
- let itemTwo = DispatchWorkItem {
- print("====\(Thread.current)====")
- }
- let itemThree = DispatchWorkItem {
- print("====\(Thread.current)====")
- }
- concuQueue.async(group: group, execute: itemOne)
- concuQueue.async(group: group, execute: itemTwo)
- concuQueue.async(group: group, execute: itemThree)
-
- //group.notify会等group里的所有任务全部完成以后才会执行(不管是同步任务还是异步任务)。
- group.notify(queue: concuQueue) {
- print("请求完成")
- }
- }
dispatch_once
- 这个函数在Swift3.0以后的时代已经被删除,因为自从Swift 1开始Swift就已经开始用dispatch_one机制在后台支持线程安全的全局lazy初始化和静态属性。static ,class背后已经在使用dispatch_once了。
-
- Swift 中单例的一种写法
- final class SingleTon: NSObject {
- static let shared = SingleTon()
- private override init() {}
- }
- 使用final,使这个类不能被继承。
- 设置初始化方法为私有,避免外部对象通过访问init方法创建单例类的实例。
延时执行
- func afterAction(_ sender: UIButton) {
-
- //GCD可以通过asyncAfter和syncAfter来提交一个延迟执行的任务
- let deadline = DispatchTime.now() + 2.0
- print("start")
- DispatchQueue.global().asyncAfter(deadline: deadline) {
- print("end")
- }
-
- //延迟执行还支持一种模式DispatchWallTime
- let walltime = DispatchWallTime.now() + 2.0
- print("start1")
- DispatchQueue.global().asyncAfter(wallDeadline: walltime) {
- print("end1")
- }
- //DispatchTime 的精度是纳秒
- //DispatchWallTime 的精度是微秒
- }
队列的挂起和恢复
- //创建并行队列
- let conQueue = DispatchQueue(label: "concurrentQueue1", attributes: .concurrent)
- //暂停一个队列
- conQueue.suspend()
- //继续队列
- conQueue.resume()
线程同步
- 信号量
- DispatchSemaphore(value: ):用于创建信号量,可以指定初始化信号量计数值,这里我们默认1.
- semaphore.wait():会判断信号量,如果为1,则往下执行。如果是0,则等待。
- semaphore.signal():代表运行结束,信号量加1,有等待的任务这个时候才会继续执行。
-
- //获取系统存在的全局队列
- let queue = DispatchQueue.global(qos: .default)
-
- //创建一个信号量,初始值为1
- let semaphore = DispatchSemaphore(value: 1)
- for i in 1...10 {
- queue.async {
- //永久等待,直到Dispatch Semaphore的计数值 >= 1
- semaphore.wait()
- print("\(i)")
- //发信号,使原来的信号计数值+1
- semaphore.signal()
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。