美文网首页
Swift3.0中的GCD

Swift3.0中的GCD

作者: 飘金 | 来源:发表于2017-04-12 09:48 被阅读0次

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中GCD的使用详情

    想看swift3.0使用GCD,请点击GCD详解 想看swift3.0闭包的使用和介绍,请点击Swift版闭包使用...

  • Swift3.0 中的GCD

  • Swift3.0中的GCD

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

  • swift3.0开发中的GCD

    队列 DispatchQueue 可以执行串行,并发。FIFO 创建队列, label 唯一的标识,建议用DNS命...

  • iOS多线程-GCD(Swift)

    GCD准确的来讲应该叫做并发编程技术,因为swift3.0后GCD使用方式有很大的变化这里用Swift来重新整理一...

  • Swift3.0 中 GCD新玩法

    取消过去的接口 说起 GCD, 大家肯定回想起类似 dispatch_async 这样的语法。 GCD 的这个语法...

  • 十三、Swift3.0之闭包的定义和GCD实际使用

    闭包定义的三种形式(无参数无返回值、有参数无返回值、有参数有返回值) Swift3.0中GCD的写法:

  • swift3.0 GCD

    随着苹果推出swift3.0,很多API都发生了变化,下面我就来总结下GCD的一些常用API用法。 首先为了方便先...

  • swift3.0 -- GCD

    1. 自己创建队列 2. 全局队列的一些说明 3. 获取一个队列 我们使用 DispatchQueue.globa...

  • Swift3.0中GCD延时函数asyncAfter的使用

    尝试了下Swift3.0中GCD的延时函数,发现貌似与之前的有挺大的不同,折腾了好一会终于算是会用了一丢丢 swi...

网友评论

      本文标题:Swift3.0中的GCD

      本文链接:https://www.haomeiwen.com/subject/lvgpattx.html