Swift 3必看:从使用场景了解GCD新API
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的更多相关文章
- Swift 3必看:新的访问控制fileprivate和open
在swift 3中新增加了两中访问控制权限 fileprivate和 open.下面将对这两种新增访问控制做详细介绍. fileprivate 在原有的swift中的 private其实并不是真正的私 ...
- 【转】 学习ios(必看经典)牛人40天精通iOS开发的学习方法【2015.12.2
原文网址:http://bbs.51cto.com/thread-1099956-1.html 亲爱的学员们: 如今,各路开发者为淘一桶金也纷纷转入iOS开发的行列.你心动了吗?想要行动吗?知道如何做 ...
- 2019最新WEB前端开发小白必看的学习路线(附学习视频教程)
2019最新WEB前端开发小白必看的学习路线(附学习视频教程).web前端自学之路:史上最全web学习路线,HTML5是万维网的核心语言,标准通用标记语言下的一个应用超文本标记语言(HTML)的第五次 ...
- Linux驱动开发必看详解神秘内核(完全转载)
Linux驱动开发必看详解神秘内核 完全转载-链接:http://blog.chinaunix.net/uid-21356596-id-1827434.html IT168 技术文档]在开始步入L ...
- 新手必看,史上最全的iOS开发教程集锦,没有之一!
最近大火的iPhone XS Max和iPhone XS,不知道有没有同学已经下手了呢?一万三的价位确实让很多人望而却步啊.据说为了赢得中国的用户,专门出了双卡双待的,可想而知中国市场这块“肥肉”人人 ...
- 程序员收藏必看系列:深度解析MySQL优化(二)
程序员收藏必看系列:深度解析MySQL优化(一) 性能优化建议 下面会从3个不同方面给出一些优化建议.但请等等,还有一句忠告要先送给你:不要听信你看到的关于优化的“绝对真理”,包括本文所讨论的内容,而 ...
- 3DS MAX玩家必看!70个提高渲染速度的小技巧
3DS MAX玩家必看!70个提高渲染速度的小技巧 (注:节省RAM不一定会加快渲染速度.请同学们根据实际情况加以利用.) 1. 尽量限制Ploygon数量,越少渲染速度越快 2. 如果使用Vray, ...
- 2019JS必看面试题
2019JS必看面试题:https://www.jianshu.com/p/f1f39d5b2a2e 1. javascript的typeof返回哪些数据类型. 答案:string,boolean,n ...
- Java编程思想重点笔记(Java开发必看)
Java编程思想重点笔记(Java开发必看) Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...
随机推荐
- python列表元组 魔法方法
1.元祖 count() 统计某个字符串的出现次数 tuple.count('22') 返回一个整数 index() 获取某个值出现的位置 2.列表 字符串可以直接转换列表 l ...
- windos常见软件库
1.护卫神软件库 http://soft.huweishen.com/special/1.html 2.护卫神windows资料库 http://v.huweishen.com/ 3.国超软件下载 h ...
- Vue.js事件处理
Vue.js事件处理 1.v-on指令 用法如下:使用v-on:指令指定其执行的具体内容或者方法名即可. <button v-on:click='num++'>giao</butto ...
- pip 安装源
pip 安装源 介绍 1.采用国内源,加速下载模块的速度 2.常用pip源: -- 豆瓣:https://pypi.douban.com/simple -- 阿里:https://mirrors.al ...
- NO16 第二关课后考试-aw-F-过滤已知的一级目录
·总结的经验:1.学会总结时学好运维的重要前提.2.通过案列或例子来总结一个技术点或者命令.3.画一张逻辑图,形象的卡通记忆这个知识技术点.4.通过管道过滤数据时,最好先输出结果,然后回退再使用管道看 ...
- anaconda 创建虚拟环境(自己版本)
首先安装anaconda(3) Anacond的介绍Anaconda指的是一个开源的Python发行版本,其包含了conda.Python等180多个科学包及其依赖项. 因为包含了大量的科学包,Ana ...
- sftp 多用户安装与配置
sftp 是 Secure File Transfer Protocol 的缩写,安全文件传送协议.可以为传输文件提供一种安全的加密方法.SFTP 为 SSH 的一部分,由于这种传输方式使用了加密/解 ...
- Linux-initramfs
1. 内核启动问题2. 解决方案2.1 ramdisk(比如initrd)2.2 tmpfs(比如initramfs)2.3 ramdisk vs ramfs2.4 临时文件系统2.4.1 观察tmp ...
- 挖洞经验 | 绕过WAF限制利用php:方法实现OOB-XXE漏洞利用
几个星期以前,作者在某个OOB-XXE漏洞测试中遇到过这样一种场景:目标应用后端系统WAF防火墙阻挡了包含DNS解析在内的所有出站请求(Outgoing Request),但最终,通过利用php:// ...
- MinGW 安装与简单实例
MinGW的下载 链接: https://pan.baidu.com/s/1JiZoyFHUWoeaxCQcUXCKgg 密码: myh3 MinGW的安装 基本上都是按提示的点击下一步操作 接下来修 ...