Swift 3.0 必看:从使用场景了解GCD新API

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
查看查看237 回复回复2 收藏收藏 分享淘帖 转播转播 分享分享 微信
查看: 237|回复: 2
收起左侧

Swift 3.0 必看:从使用场景了解GCD新API

[复制链接]
swifter 发表于 2016-10-21 03:01:17 | 显示全部楼层 |阅读模式
快来登录
获取最新的苹果动态资讯
收藏热门的iOS等技术干货
拷贝下载Swift Demo源代码
本帖最后由 swifter 于 2016-10-21 03:48 编辑



刚才在Swift大拇指上发了《Swift 3.0 必看:给DispatchQueue扩展实现被废Dispatch once原有功能》,现在继续。

欢迎订阅我在全球最大的Swift开发者社区——敏捷大拇指Swifthumb.com)上的淘帖专辑《Swift 3.0 必看语法变动》,有更多的Swift 3.0语法变动方面的资料,一旦有更新,就会通知到你。

Swift 3.0 必看 系列

Swift 3.0 必看:从使用场景了解GCD新API - 敏捷大拇指 - Swift 3.0 必看 系列


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

Swift 3.0 必看:从使用场景了解GCD新API 1

Swift 3.0 必看:从使用场景了解GCD新API - 敏捷大拇指 - Swift 3.0 必看:从使用场景了解GCD新API 1





1、dispatch_async

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

[Swift] 纯文本查看 复制代码
DispatchQueue.global().async {
    // code
    DispatchQueue.main.async {
        // 主线程中
    }
}


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

[Swift] 纯文本查看 复制代码
class DispatchQueue : DispatchObject {
    public  class var main: DispatchQueue 
    public class func global(qos: DispatchQoS.QoSClass = default) -> DispatchQueue
}





2、sync

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

[Swift] 纯文本查看 复制代码
DispatchQueue.global().sync {
    // 同步执行
}





3、优先级:DispatchQoS

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

  • DISPATCH_QUEUE_PRIORITY_HIGH
  • DISPATCH_QUEUE_PRIORITY_DEFAULT
  • DISPATCH_QUEUE_PRIORITY_LOW
  • DISPATCH_QUEUE_PRIORITY_BACKGROUND


现在则改为了QoSClass枚举:

[Swift] 纯文本查看 复制代码
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 }
    }


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

Swift 3.0 必看:从使用场景了解GCD新API 2

Swift 3.0 必看:从使用场景了解GCD新API - 敏捷大拇指 - Swift 3.0 必看:从使用场景了解GCD新API 2


和原有的对应关系是:

[Swift] 纯文本查看 复制代码
* DISPATCH_QUEUE_PRIORITY_HIGH:         .userInitiated
* DISPATCH_QUEUE_PRIORITY_DEFAULT:      .default
* DISPATCH_QUEUE_PRIORITY_LOW:          .utility
* DISPATCH_QUEUE_PRIORITY_BACKGROUND:   .background





4、创建队列

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

[Swift] 纯文本查看 复制代码
// 同步队列
let serialQueue = DispatchQueue(label: "queuename")

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





5、推迟时间后执行

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

[Swift] 纯文本查看 复制代码
let delay = DispatchTime.now() + DispatchTimeInterval.seconds(60)
DispatchQueue.main.asyncAfter(deadline: delay) { 
    // 延迟执行
}


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

[Swift] 纯文本查看 复制代码
let three = DispatchTime.now() + 3.0


因为DispatchTime中自定义了+号。

[Swift] 纯文本查看 复制代码
public func +(time: DispatchTime, seconds: Double) -> DispatchTime





6、DispatchGroup

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

[Swift] 纯文本查看 复制代码
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

[Swift] 纯文本查看 复制代码
group.wait()





7、DispatchWorkItem

使用DispatchWorkItem代替原来的dispatch_block_t。

在DispatchQueue执行操作除了直接传了一个() -> Void类型的闭包外,还可以传入一个DispatchWorkItem。

[Swift] 纯文本查看 复制代码
    public func sync(execute workItem: DispatchWorkItem)

    public func async(execute workItem: DispatchWorkItem)


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

[Swift] 纯文本查看 复制代码
public init(qos: DispatchQoS = default, flags: DispatchWorkItemFlags = default, block: @escaping @convention(block) () -> ())

let workItem = DispatchWorkItem { 
    // TODO:
}


DispatchWorkItemFlags枚举中assignCurrentContext表示QoS根据创建时的context决定。

值得一提的是DispatchWorkItem也有wait方法,使用方式和group一样。调用会等待这个workItem执行完。

[Swift] 纯文本查看 复制代码
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")





8、barrier

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

现在属性放在了DispatchWorkItemFlags里。

[Swift] 纯文本查看 复制代码
let wirte = DispatchWorkItem(flags: .barrier) { 
    // write data
}
let dataQueue = DispatchQueue(label: "data", attributes: .concurrent)
dataQueue.async(execute: wirte)





9、信号量

为了线程安全的统计数量,我们会使用信号量作计数。原来的dispatch_semaphore_t现在用DispatchSemaphore对象表示。

初始化方法只有一个,传入一个Int类型的数。

[Swift] 纯文本查看 复制代码
let semaphore = DispatchSemaphore(value: 5)

 // 信号量减一
semaphore.wait()

 //信号量加一
semaphore.signal()





10、dispatch_once被废弃

在Swift 3中已经被废弃了。

简单的建议就是一些初始化场景就用懒加载吧。

[Swift] 纯文本查看 复制代码
// 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

Swift 3.0 必看:新增的两种访问控制权限 fileprivate和open

Swift 3.0 必看:集合方法flatten()重命名为joined()

Swift 3.0 必看:typealias支持泛型

Swift 3.0 必看:#selector获取属性的getter和setter方法

Swift 3.0 必看:foundation中数据引用类型改为值类型

Swift 3.0 必看:dynamicType废除,用type(of: )代替

Swift 3.0 必看:给DispatchQueue扩展实现被废Dispatch once原有功能

Swift 3.0 必看:从使用场景了解GCD新API

Swift 3.0 必看:sizeof移进MemoryLayout

Swift 3.0 必看:@noescape走了, @escaping来了

Swift 3.0 必看:Swift中被忽略的@noescape

同时,欢迎订阅我在全球最大的Swift开发者社区——敏捷大拇指Swifthumb.com)上的淘帖专辑《Swift 3.0 必看语法变动》,有更多的Swift 3.0语法变动方面的资料,一旦有更新,就会通知到你。




作者:没故事的卓同学

都看到这里了,就把这篇资料推荐给您的好朋友吧,让他们也感受一下。

回帖是一种美德,也是对楼主发帖的尊重和支持。

*声明:敏捷大拇指是全球最大的Swift开发者社区、苹果粉丝家园、智能移动门户,所载内容仅限于传递更多最新信息,并不意味赞同其观点或证实其描述;内容仅供参考,并非绝对正确的建议。本站不对上述信息的真实性、合法性、完整性做出保证;转载请注明来源并加上本站链接,敏捷大拇指将保留所有法律权益。如有疑问或建议,邮件至marketing@swifthumb.com

*联系:微信公众平台:“swifthumb” / 腾讯微博:@swifthumb / 新浪微博:@swifthumb / 官方QQ一群:343549891(满) / 官方QQ二群:245285613 ,需要报上用户名才会被同意进群,请先注册敏捷大拇指

嗯,不错!期待更多好内容,支持一把:
支持敏捷大拇指,用支付宝支付10.24元 支持敏捷大拇指,用微信支付10.24元

评分

参与人数 1金钱 +10 贡献 +10 专家分 +10 收起 理由
Anewczs + 10 + 10 + 10 32个赞!专家给力!

查看全部评分

本帖被以下淘专辑推荐:

手表哥 发表于 2016-10-25 09:17:47 | 显示全部楼层
为什么我一直觉得GCD很难掌握呢
攻城狮 发表于 4 天前 | 显示全部楼层
谢楼主,对GCD研究得很深入。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

做任务,领红包。
我要发帖

分享扩散

都看到这里了,就把这资料推荐给您的好朋友吧,让他们也感受一下。
您的每一位朋友访问此永久链接后,您都将获得相应的金钱积分奖励
热门推荐

合作伙伴

Swift小苹果

  • 北京治世天下科技有限公司
  • ©2014-2016 敏捷大拇指
  • 京ICP备14029482号
  • Powered by Discuz! X3.1 Licensed
  • swifthumb Wechat Code
  •   
快速回复 返回顶部 返回列表