https://www.jianshu.com/p/fc78dab5736f
在学习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
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
https://www.jianshu.com/p/fc78dab5736f的更多相关文章
- [转]https://www.jianshu.com/p/06443248f4d8
eos是什么? 原文 https://www.jianshu.com/p/06443248f4d8 简介 用一句话来定义eos,即:区块链操作系统,支持在它之上构建dapp,支持智能合约.帐户.身份验 ...
- Zabbix调优不完全指南(https://www.jianshu.com/p/2d911d55448f)
从学习搭建zabbix到完成各类监控.调优.二次开发已经过去了两年,期间通过QQ学习群.zabbix官方社区.各个技术博客整理学习了不少关于各种报错的处理方法,现在将常见的一些报错处理方法整理出来分享 ...
- 接口测试之——Charles抓包及常见问题解决(转载自https://www.jianshu.com/p/831c0114179f)
简介 Charles其实是一款代理服务器,通过成为电脑或者浏览器的代理,然后截取请求和请求结果达到分析抓包的目的.该软件是用Java写的,能够在Windows,Mac,Linux上使用,安装Charl ...
- jar与war包区别,转自https://www.jianshu.com/p/3b5c45e8e5bd
https://www.jianshu.com/p/3b5c45e8e5bd
- fastdfs(https://www.jianshu.com/p/1c71ae024e5e)
参考 官方网站:https://github.com/happyfish100/ 配置文档:https://github.com/happyfish100/fastdfs/wiki/ 参考资料:htt ...
- https://www.jianshu.com/p/1038c6170775
import os # 方法一: os.walk实现 def items_dir(rootname): l = [] for main_dir, dirs, file_name_list in os. ...
- Redis 单线程却能支撑高并发 - 简书 https://www.jianshu.com/p/2d293482f272
小结: 1.在 I/O 多路复用模型中,最重要的函数调用就是 select,该方法的能够同时监控多个文件描述符的可读可写情况:2.Redis 服务采用 Reactor 的方式来实现文件事件处理器(每一 ...
- 当我写下Map<String,Object> map = new HashMap<>() https://www.jianshu.com/p/6b2e350e99be
当我写下Map<String,Object> map = new HashMap<>();我到底在写什么? 我什么时候会写HashMap? 一个函数同时需要返回 多种 状态的情 ...
- Asp.Net Core 第01局:项目创建和部署 转载https://www.jianshu.com/p/9c9750e23b3e
总目录 一.前言 本文通过从项目创建到部署,简单介绍Asp.Net Core. 二.环境 1.Visual Studio 2017 2.Asp.Net Core 2.2 三.开局 第一手:创建项目 ...
随机推荐
- 通过SparkListener监控spark应用
监控spark应用的方式比较多,比如spark on yarn可以通过yarnClient api监控.这里介绍的是spark内置的一种监控方式 如果是sparkStreaming,对应的则是stre ...
- ubuntu安装discourse论坛----结合在apache服务上建立虚拟主机
指导操作:https://github.com/discourse/discourse/blob/master/docs/INSTALL-cloud.md 一.先安装 Docker / Git: wg ...
- 第3节 sqoop:3、sqoop的入门测试使用
3.5. Sqoop的数据导入 “导入工具”导入单个表从RDBMS到HDFS.表中的每一行被视为HDFS的记录.所有记录都存储为文本文件的文本数据(或者Avro.sequence文件等二进制数据) 列 ...
- 阿里云https+nginx服务搭建
购买证书 通过控制台进入CA证书服务,点击右上角的购买证书,进入如下图的界面,选择免费的Symantec的DV SSL. 一路点过去,然后回到证书服务主页,会出现一条订单信息,点击补全,如下图所示. ...
- MyBatis笔记(一)
MyBatis学习随笔 第一个MyBatis项目 创建项目 导入maven依赖,根据需要选择性添加mysql/oracle,spring,spring-mybatis等依赖,这里就不一一列出了 < ...
- PHP计划任务
server 2008:D:\SOFT_PHP_PACKAGE\php\php-cgi.exe -f D:\wwwroot\tlbuyuncom\wwwroot\Up_Data.phpPHP路径 -f ...
- Web服务器:Apache的安装使用
Apache我们很熟悉,已经用了不短时间的tomcat就是apache公司开发的,那么这款以公司命名的所谓的Web服务器Apache,又到底什么呢? 一.概念 Apache是一个静态的Web服务器,是 ...
- 自制spring中bean加载机制,仅做笔记自用
- SQL注入过WAF(11.4 第三十三天)
WAF是什么? Web应用防护系统(也称:网站应用级入侵防御系统.英文:Web Application Firewall,简称: WAF).也叫Web防火墙,主要是对Web特有入侵方式的加强防护,如D ...
- 关于如何实现一个Saga分布式事务框架的思考
关于Saga模式的介绍,已经有一篇文章介绍的很清楚了,链接在这里:分布式事务:Saga模式. 关于TCC模式的介绍,也已经有一篇文章介绍的很清楚了,链接在这里:关于如何实现一个TCC分布式事务框架的一 ...