https://www.jianshu.com/p/fc78dab5736f

2016.10.06 21:59*

在学习Swift 3的过程中整理了一些笔记,如果想看其他相关文章可前往《Swift 3必看》系列目录

swift 3中对C层级的GCD的API进行了彻头彻尾的改变。本文将从实际使用场景来了解一下新的api使用。

dispatch_async

一个常见的场景就是在一个全局队列进行一些操作后切换到主线程配置UI。现在是这么写:

DispatchQueue.global().async {
// code
DispatchQueue.main.async {
// 主线程中
}
}

global()是一个有着默认参数的静态函数:

class DispatchQueue : DispatchObject {
public class var main: DispatchQueue
public class func global(qos: DispatchQoS.QoSClass = default) -> DispatchQueue
}

sync

如果想同步执行操作,和async类似,调用sync就可以了:

DispatchQueue.global().sync {
// 同步执行
}

优先级:DispatchQoS

我们知道,GCD 的默认队列优先级有四个:

  • DISPATCH_QUEUE_PRIORITY_HIGH
  • DISPATCH_QUEUE_PRIORITY_DEFAULT
  • DISPATCH_QUEUE_PRIORITY_LOW
  • DISPATCH_QUEUE_PRIORITY_BACKGROUND

现在则改为了QoSClass枚举

 public enum QoSClass {

        case background

        case utility

        case `default`

        case userInitiated

        case userInteractive

        case unspecified

        public init?(rawValue: qos_class_t)

        public var rawValue: qos_class_t { get }
}

这些命名比原先的更加友好,能更好表达这个操作的意图。

和原有的对应关系是:

* DISPATCH_QUEUE_PRIORITY_HIGH:         .userInitiated
* DISPATCH_QUEUE_PRIORITY_DEFAULT: .default
* DISPATCH_QUEUE_PRIORITY_LOW: .utility
* DISPATCH_QUEUE_PRIORITY_BACKGROUND: .background

创建队列

DispatchQueue的默认初始化方法创建的就是一个同步队列,如果要创建并发的队列,在attributes中声明concurrent。

// 同步队列
let serialQueue = DispatchQueue(label: "queuename") // 并发队列
let concurrentQueue = DispatchQueue(label: "queuename", attributes: .concurrent)

推迟时间后执行

原先的dispatch_time_t现在由DispatchTime对象表示。可以用静态方法now获得当前时间,然后再通过加上一个DispatchTimeInterval枚举来获得一个需要延迟的时间。

let delay = DispatchTime.now() + DispatchTimeInterval.seconds(60)
DispatchQueue.main.asyncAfter(deadline: delay) {
// 延迟执行
}

这里也可以直接加上一个秒数。

let three = DispatchTime.now() + 3.0

因为DispatchTime中自定义了<code>+</code>号。


public func +(time: DispatchTime, seconds: Double) -> DispatchTime

DispatchGroup

如果想在dispatch_queue中所有的任务执行完成后再做某种操作可以使用DispatchGroup。原先的dispatch_group_t由现在的DispatchGroup对象代替。

let group = DispatchGroup()

let queueBook = DispatchQueue(label: "book")
queueBook.async(group: group) {
// 下载图书
}
let queueVideo = DispatchQueue(label: "video")
queueVideo.async(group: group) {
// 下载视频
} group.notify(queue: DispatchQueue.main) {
// 下载完成
}

DispatchGroup会在组里的操作都完成后执行notify。
如果有多个并发队列在一个组里,我们想在这些操作执行完了再继续,调用wait

group.wait()

DispatchWorkItem

使用DispatchWorkItem代替原来的<code>dispatch_block_t</code>。
在DispatchQueue执行操作除了直接传了一个<code>() -> Void</code>类型的闭包外,还可以传入一个DispatchWorkItem。


public func sync(execute workItem: DispatchWorkItem) public func async(execute workItem: DispatchWorkItem)

DispatchWorkItem的初始化方法可以配置Qos和DispatchWorkItemFlags,但是这两个参数都有默认参数,所以也可以只传入一个闭包。

    public init(qos: DispatchQoS = default, flags: DispatchWorkItemFlags = default, block: @escaping @convention(block) () -> ())

let workItem = DispatchWorkItem {
// TODO:
}

DispatchWorkItemFlags枚举中assignCurrentContext表示QoS根据创建时的context决定。
值得一提的是DispatchWorkItem也有wait方法,使用方式和group一样。调用会等待这个workItem执行完。

let myQueue = DispatchQueue(label: "my.queue", attributes: .concurrent)
let workItem = DispatchWorkItem {
sleep(1)
print("done")
}
myQueue.async(execute: workItem)
print("before waiting")
workItem.wait()
print("after waiting")

barrier

假设我们有一个并发的队列用来读写一个数据对象。如果这个队列里的操作是读的,那么可以多个同时进行。如果有写的操作,则必须保证在执行写入操作时,不会有读取操作在执行,必须等待写入完成后才能读取,否则就可能会出现读到的数据不对。在之前我们用dipatch_barrier实现。
现在属性放在了DispatchWorkItemFlags里。

let wirte = DispatchWorkItem(flags: .barrier) {
// write data
}
let dataQueue = DispatchQueue(label: "data", attributes: .concurrent)
dataQueue.async(execute: wirte)

信号量

为了线程安全的统计数量,我们会使用信号量作计数。原来的dispatch_semaphore_t现在用DispatchSemaphore对象表示。
初始化方法只有一个,传入一个Int类型的数。


let semaphore = DispatchSemaphore(value: 5) // 信号量减一
semaphore.wait() //信号量加一
semaphore.signal()

dispatch_once被废弃

在swift 3中已经被废弃了。
简单的建议就是一些初始化场景就用懒加载吧。

// Examples of dispatch_once replacements with global or static constants and variables.
// In all three, the initialiser is called only once. // Static properties (useful for singletons).
class Object {
static let sharedInstance = Object()
} // Global constant.
let constant = Object() // Global variable.
var variable: Object = {
let variable = Object()
variable.doSomething()
return variable
}()

欢迎关注我的微博:@没故事的卓同学

相关链接:
SE0088-Modernize libdispatch for Swift 3 naming conventions
Concurrent Programming With GCD in Swift 3

作者:没故事的卓同学
链接:https://www.jianshu.com/p/fc78dab5736f
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

Swift 3必看:从使用场景了解GCD新API的更多相关文章

  1. Swift 3必看:新的访问控制fileprivate和open

    在swift 3中新增加了两中访问控制权限 fileprivate和 open.下面将对这两种新增访问控制做详细介绍. fileprivate 在原有的swift中的 private其实并不是真正的私 ...

  2. 【转】 学习ios(必看经典)牛人40天精通iOS开发的学习方法【2015.12.2

    原文网址:http://bbs.51cto.com/thread-1099956-1.html 亲爱的学员们: 如今,各路开发者为淘一桶金也纷纷转入iOS开发的行列.你心动了吗?想要行动吗?知道如何做 ...

  3. 2019最新WEB前端开发小白必看的学习路线(附学习视频教程)

    2019最新WEB前端开发小白必看的学习路线(附学习视频教程).web前端自学之路:史上最全web学习路线,HTML5是万维网的核心语言,标准通用标记语言下的一个应用超文本标记语言(HTML)的第五次 ...

  4. Linux驱动开发必看详解神秘内核(完全转载)

    Linux驱动开发必看详解神秘内核 完全转载-链接:http://blog.chinaunix.net/uid-21356596-id-1827434.html   IT168 技术文档]在开始步入L ...

  5. 新手必看,史上最全的iOS开发教程集锦,没有之一!

    最近大火的iPhone XS Max和iPhone XS,不知道有没有同学已经下手了呢?一万三的价位确实让很多人望而却步啊.据说为了赢得中国的用户,专门出了双卡双待的,可想而知中国市场这块“肥肉”人人 ...

  6. 程序员收藏必看系列:深度解析MySQL优化(二)

    程序员收藏必看系列:深度解析MySQL优化(一) 性能优化建议 下面会从3个不同方面给出一些优化建议.但请等等,还有一句忠告要先送给你:不要听信你看到的关于优化的“绝对真理”,包括本文所讨论的内容,而 ...

  7. 3DS MAX玩家必看!70个提高渲染速度的小技巧

    3DS MAX玩家必看!70个提高渲染速度的小技巧 (注:节省RAM不一定会加快渲染速度.请同学们根据实际情况加以利用.) 1. 尽量限制Ploygon数量,越少渲染速度越快 2. 如果使用Vray, ...

  8. 2019JS必看面试题

    2019JS必看面试题:https://www.jianshu.com/p/f1f39d5b2a2e 1. javascript的typeof返回哪些数据类型. 答案:string,boolean,n ...

  9. Java编程思想重点笔记(Java开发必看)

    Java编程思想重点笔记(Java开发必看)   Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...

随机推荐

  1. Redis使用守护进程启动sentinel并指定其日志目录

    正常redis-server可以通过配置文件来指定守护进程启动以及指定日志路径,但sentinel就不一样了.正常启动redis的sentinel时,进程会直接在前台跑,一退出sentinel进程就关 ...

  2. Ubuntu 18.04 安装ROS 配置环境 没有那个文件或目录的解决办法

    Ubuntu 18.04版本,在安装ROS时运行  source ~/.bashrc 命令时出现没有那个文件夹或目录 或 No such file or directory的错误 在经过一番查询后发现 ...

  3. ss性能

    ss是Socket Statistics的缩写.顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容.但ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信 ...

  4. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 辅助类:内容居中

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  5. SpringIOC初始化过程源码跟踪及学习

    Spring版本 4.3.2,ssm框架 代码过宽,可以shift + 鼠标滚轮 左右滑动查看 web.xml <!--配置获取项目的根路径,java类中使用System.getProperty ...

  6. 10. Regular Expression Matching正则表达式匹配

    Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...

  7. 剑指offer,双指针法,vector输出不完美

    原因:由于在第一个res push_back给allRes的时候allRes的列已经确定,所以在输出的时候会输出一些多余的东西,在输出的时候不好处理 #include <iostream> ...

  8. 基于AQS自己实现一个同步器

    前面说了这个多,我们可以自己尝试实现一个同步器,我们可以简单的参考一下ReentrantLock这个类的实现方式,我们就简单的实现一个不可重入的独占锁吧! 一.简单分析ReentrantLock的结构 ...

  9. 微信小程序学习开发笔记

    首先注册小程序开账号,下载开发工具之后,先啃官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/ ,把小程序的基本的代码框架 ...

  10. C语言拾遗——strtok

    C语言拾遗——strtok 今天刷PAT的时候用到了这个strtok函数,顺手就记录一下 strtok函数包含于头文件string.h 语法:char *strtok( char *str1, con ...