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. mysql 三表索引优化

    建表语句 CREATE TABLE IF NOT EXISTS `phone`( `phoneid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `card` ...

  2. (十)微信小程序---上传图片chooseImage

    官方文档 示例一 wxml <view bindtap="uploadImage">请上传图片</view> <image wx:for=" ...

  3. windows制作动态链接库和使用一

    制作: //myDll.h _declspec(dllexport) int add(int a,int b); _declspec(dllexport) int sub(int a,int b); ...

  4. REVISITING FINE-TUNING FOR FEW-SHOT LEARNING

    https://arxiv.org/pdf/1910.00216.pdf   明天看

  5. Elasticsearch学习入门

    一.关于Elasticsearch 1.特点 Elasticsearch基于全文搜索引擎 Apache Lucene ,由Java开发而来,面向API进行搜索, Restful 风格,分布式文件存储. ...

  6. Aop配置时候的一些问题

    编写切面,并在ApplicationContest.xml 中相关AOP及切面的配置完全正确的情况下,运行报错如下: Exception in thread "main" org. ...

  7. springboot学习3事务控制

    springboot学习3事务控制 spring的事务控制本质上是通过aop实现的. 在springboot中使用时,可以通过注解@Transactional进行类或者方法级别的事务控制,也可以自己通 ...

  8. Vulkan SDK Demo 之一 熟悉

    DiligentEngine的API是D3d11和D3D12风格的,vulkan也被封装成了这种风格的API. 在了解Diligent Engine是如何对vulkan进行封装之前,我准备先学习下Vu ...

  9. Java中数组的创建

    Java中数组的使用 1.普通数组变量的定义: //数组 //1.数组是Java中很重要的一部分,今天对数组进行了大致的了解,Java中的数组和C中数组还是有一定的区别的 //以下是总结的几种方法 p ...

  10. apache端口修改为80

    apache端口莫名改变为443,访问网址失败,修改Apache端口: 1.打开目录(实际而定): C:\xampp\apache\conf 编辑httpd.conf 2.ctrl + f  搜索li ...