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

451 查看

11225849-739dee13f2529a0f

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

dispatch_async

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

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

sync

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

优先级:DispatchQoS

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

  • DISPATCH_QUEUE_PRIORITY_HIGH
  • DISPATCH_QUEUE_PRIORITY_DEFAULT
  • DISPATCH_QUEUE_PRIORITY_LOW
  • DISPATCH_QUEUE_PRIORITY_BACKGROUND

现在则改为了QoSClass枚举

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

12225849-a1874612db1bc1ba

和原有的对应关系是:

创建队列

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

推迟时间后执行

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

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

因为DispatchTime中自定义了+号。

DispatchGroup

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

DispatchGroup会在组里的操作都完成后执行notify。
如果有多个并发队列在一个组里,我们想在这些操作执行完了再继续,调用wait

DispatchWorkItem

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

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

DispatchWorkItemFlags枚举中assignCurrentContext表示QoS根据创建时的context决定。
值得一提的是DispatchWorkItem也有wait方法,使用方式和group一样。调用会等待这个workItem执行完。

barrier

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

信号量

为了线程安全的统计数量,我们会使用信号量作计数。原来的dispatch_semaphore_t现在用DispatchSemaphore对象表示。
初始化方法只有一个,传入一个Int类型的数。

dispatch_once被废弃

在swift 3中已经被废弃了。
简单的建议就是一些初始化场景就用懒加载吧。

欢迎关注我的微博:@没故事的卓同学

相关链接:
SE0088-Modernize libdispatch for Swift 3 naming conventions
Concurrent Programming With GCD in Swift 3