swift 3.0 GCD使用
来源:互联网 发布:excel数据统计图表 编辑:程序博客网 时间:2024/06/07 06:23
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中自定义了+
号。
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代替原来的dispatch_block_t
。
在DispatchQueue执行操作除了直接传了一个() -> Void
类型的闭包外,还可以传入一个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}()
- swift 3.0 GCD使用
- Swift-GCD的基本使用(Swift 3.0)
- swift中的GCD简单使用
- swift 3.0 闭包,项目使用例子,结合GCD
- swift--Swift 3.0实战:从使用场景了解GCD新API
- Swift 3.0中GCD的常用方法
- Swift 3.0 【Swift 3.0 中 GCD 的改变】
- GCD学习 - swift GCD使用指南
- iOS开发 - Swift使用GCD实现计时器功能
- Swift-->GCD,NSThread,NSBlockOperation多线程使用(主线程回调)
- gcd(swift)
- Swift之GCD(一)
- swift之GCD(二)
- gcd的封装(swift)
- iOS多线程(GCD)(swift)
- 【iOS】Swift GCD-上
- 【iOS】Swift GCD-下
- 【iOS】Swift GCD-上
- Android混淆步骤,混淆结果查看以及混淆后出现的问题和衍生问题
- Spring学习心得(17)-- 切入点表达式
- 双二阶滤波器
- CodeForces 777B Game of Credit Cards【贪心】
- C++数组与指针的区别以及数组指针/指针数组实例介绍
- swift 3.0 GCD使用
- poj 3928树状数组
- POPWindow的使用技巧盲点
- [转]解决每次从cmd进入sqlplus,都得重新设置pagesize、linesize的问题
- 链表简单创建查找
- 浅谈ORACLE AWR single instance 一
- c/c++ union
- Day005: linked list cycle
- 用android studio创建手机用户界面