本文是对这篇文章中GCD的使用方法的语法翻译
另外推荐这篇
看完以上两篇,我保证你的GCD差不多都掌握了
- Swift2.3与swift3.0全局队列优先级对应关系(高 > 默认 > 低 > 后台)
DISPATCH_QUEUE_PRIORITY_HIGH .userInitiated
DISPATCH_QUEUE_PRIORITY_DEFAULT .default
DISPATCH_QUEUE_PRIORITY_LOW .utility
DISPATCH_QUEUE_PRIORITY_BACKGROUND .background
修条环城路(创建一个子线程)
// Swift2.3
let queue = dispatch_queue_create("环城路", nil)
// 异步执行
dispatch_async(queue) {
// 给碴土车走的(耗时操作)
}
// Swift3.0
DispatchQueue(label: "环城路").async {
// 给碴土车走的(耗时操作)
}
走城市自带的环城(使用全局队列)
// Swift2.3
//高 > 默认 > 低 > 后台
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
// DISPATCH_QUEUE_PRIORITY_HIGH
// DISPATCH_QUEUE_PRIORITY_DEFAULT
// DISPATCH_QUEUE_PRIORITY_LOW
// DISPATCH_QUEUE_PRIORITY_BACKGROUND
let queue = dispatch_get_global_queue(priority, 0)
// 异步执行
dispatch_async(queue) {
// 给碴土车走的(耗时操作)
}
// Swift3.0
let qos: DispatchQoS.QoSClass = .default
// .userInitiated > .default > .utility > .background
DispatchQueue.global(qos: qos).async {
// 给碴土车走的(耗时操作)
}
同步执行串行队列
// Swift2.3
let queue = dispatch_queue_create("syn.serial.queue", DISPATCH_QUEUE_SERIAL)
for i in 0..<3 {
dispatch_sync(queue) {
currentThreadSleep(1)
print("当前执行线程:\(getCurrentThread())")
print("执行\(i)")
}
print("\(i)执行完毕")
}
print("所有队列使用同步方式执行完毕")
// Swift3.0
for i in 0..<3 {
DispatchQueue(label: "syn.serial.queue").sync() {
currentThreadSleep(1)
print("当前执行线程:\(Thread.current)")
print("执行\(i.toEmoji)")
}
print("\(i.toEmoji)执行完毕")
}
同步执行并行队列
// Swift2.3
let queue = dispatch_queue_create("syn.concurrent.queue", DISPATCH_QUEUE_CONCURRENT)
for i in 0..<3 {
dispatch_sync(queue) {
currentThreadSleep(1)
print("当前执行线程:\(getCurrentThread())")
print("执行\(i)")
}
print("\(i)执行完毕")
}
print("所有队列使用同步方式执行完毕")
// Swift3.0
for i in 0..<3 {
DispatchQueue(label: "syn.concurrent.queue", attributes: .concurrent).sync() {
currentThreadSleep(1)
print("当前执行线程:\(Thread.current)")
print("执行\(i.toEmoji)")
}
print("\(i.toEmoji)执行完毕")
}
异步执行串行队列
// Swift2.3
let serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL)
let queue = dispatch_queue_create("asyn.serial.queue", DISPATCH_QUEUE_SERIAL)
for i in 0..<3 {
dispatch_async(queue) {
currentThreadSleep(Double(arc4random()%3))
let currentThread = getCurrentThread()
dispatch_sync(serialQueue, { //同步锁
print("Sleep的线程\(currentThread)")
print("当前输出内容的线程\(getCurrentThread())")
print("执行\(i):\(queue)\n")
})
}
print("\(i)添加完毕\n")
}
print("使用异步方式添加队列")
// Swift3.0
let serialQueue = DispatchQueue(label: "serialQueue")
for i in 0..<3 {
group.enter()
DispatchQueue(label: "asyn.serial.queue").async(group: group) {
self.currentThreadSleep(Double(arc4random()%3))
let currentThread = Thread.current
serialQueue.sync { //同步锁
group.leave()
print("①Sleep的线程\(currentThread)")
print("②当前输出内容的线程\(Thread.current)")
print("③执行\(i.toEmoji):\(queue)\n")
}
}
print("\(i.toEmoji)添加完毕\n")
}
异步执行并行队列
// Swift2.3
let serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL)
let queue = dispatch_queue_create("asyn.concurrent.queue", DISPATCH_QUEUE_CONCURRENT)
for i in 0..<3 {
dispatch_async(queue) {
currentThreadSleep(Double(arc4random()%3))
let currentThread = getCurrentThread()
dispatch_sync(serialQueue, { //同步锁
print("Sleep的线程\(currentThread)")
print("当前输出内容的线程\(getCurrentThread())")
print("执行\(i):\(queue)\n")
})
}
print("\(i)添加完毕\n")
}
print("使用异步方式添加队列")
// Swift3.0
let serialQueue = DispatchQueue(label: "serialQueue")
for i in 0..<3 {
group.enter()
DispatchQueue(label: "asyn.concurrent.queue", attributes: .concurrent).async(group: group) {
self.currentThreadSleep(Double(arc4random()%3))
let currentThread = Thread.current
serialQueue.sync { //同步锁
group.leave()
print("①Sleep的线程\(currentThread)")
print("②当前输出内容的线程\(Thread.current)")
print("③执行\(i.toEmoji):\(queue)\n")
}
}
print("\(i.toEmoji)添加完毕\n")
}
print("使用异步方式添加队列")
延迟执行
// Swift2.3
//dispatch_time用于计算相对时间,当设备睡眠时,dispatch_time也就跟着睡眠了
let delayTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(time * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, getGlobalQueue()) {
print("执行线程:\(getCurrentThread())\ndispatch_time: 延迟\(time)秒执行\n")
}
//dispatch_walltime用于计算绝对时间,而dispatch_walltime是根据挂钟来计算的时间,即使设备睡眠了,他也不会睡眠。
let nowInterval = NSDate().timeIntervalSince1970
var nowStruct = timespec(tv_sec: Int(nowInterval), tv_nsec: 0)
let delayWalltime = dispatch_walltime(&nowStruct, Int64(time * Double(NSEC_PER_SEC)))
dispatch_after(delayWalltime, getGlobalQueue()) {
print("执行线程:\(getCurrentThread())\ndispatch_walltime: 延迟\(time)秒执行\n")
}
// Swift3.0
let semaphore = DispatchSemaphore(value: 0)
let queue = getGlobalQueue()
let delaySecond = DispatchTimeInterval.seconds(time)
print(Date())
let delayTime = DispatchTime.now() + delaySecond
queue.asyncAfter(deadline: delayTime) {
print("执行线程:\(Thread.current)\ndispatch_time: 延迟\(time)秒执行\n",Date())
semaphore.signal()
}
//DispatchWallTime用于计算绝对时间,而DispatchWallTime是根据挂钟来计算的时间,即使设备睡眠了,他也不会睡眠。
// let nowInterval = Date().timeIntervalSince1970
// let nowStruct = timespec(tv_sec: Int(nowInterval), tv_nsec: 0)
// let delayWalltime = DispatchWallTime(timespec: nowStruct)
let delayWalltime = DispatchWallTime.now() + delaySecond
queue.asyncAfter(wallDeadline: delayWalltime) {
print("执行线程:\(Thread.current)\ndispatch_walltime: 延迟\(time)秒执行\n", Date())
}
semaphore.wait()
设置全局队列的优先级
// Swift2.3
let queueHeight: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)
let queueDefault: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
let queueLow: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)
let queueBackground: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)
//优先级不是绝对的,大体上会按这个优先级来执行。 一般都是使用默认(default)优先级
dispatch_async(queueLow) {
print("Low:\(getCurrentThread())")
}
dispatch_async(queueBackground) {
print("Background:\(getCurrentThread())")
}
dispatch_async(queueDefault) {
print("Default:\(getCurrentThread())")
}
dispatch_async(queueHeight) {
print("High:\(getCurrentThread())")
}
// Swift3.0
let queueHeight = DispatchQueue.global(qos: .userInitiated)
let queueDefault = DispatchQueue.global(qos: .default)
let queueLow = DispatchQueue.global(qos: .utility)
let queueBackground = DispatchQueue.global(qos: .background)
let group = DispatchGroup()
//优先级不是绝对的,大体上会按这个优先级来执行。 一般都是使用默认(default)优先级
queueLow.async(group: group) {
print("Low:\(Thread.current)")
}
queueBackground.async(group: group) {
print("Background:\(Thread.current)")
}
queueDefault.async(group: group) {
print("Default:\(Thread.current)")
}
queueHeight.async(group: group) {
print("High:\(Thread.current)")
}
设置自建队列优先级
// Swift2.3
//优先级的执行顺序也不是绝对的
//给serialQueueHigh设定DISPATCH_QUEUE_PRIORITY_HIGH优先级
let serialQueueHigh = getSerialQueue("cn.zeluli.serial1")
dispatch_set_target_queue(serialQueueHigh, getGlobalQueue(DISPATCH_QUEUE_PRIORITY_HIGH))
let serialQueueLow = getSerialQueue("cn.zeluli.serial1")
dispatch_set_target_queue(serialQueueLow, getGlobalQueue(DISPATCH_QUEUE_PRIORITY_LOW))
dispatch_async(serialQueueLow) {
print("低:\(getCurrentThread())")
}
dispatch_async(serialQueueHigh) {
print("高:\(getCurrentThread())")
}
// Swift3.0
//优先级的执行顺序也不是绝对的
//给serialQueueHigh设定DISPATCH_QUEUE_PRIORITY_HIGH优先级
let serialQueueHigh = DispatchQueue(label: "cn.zeluli.serial1")
DispatchQueue.global(qos: .userInitiated).setTarget(queue: serialQueueHigh)
let serialQueueLow = DispatchQueue(label: "cn.zeluli.serial1")
DispatchQueue.global(qos: .utility).setTarget(queue: serialQueueLow)
serialQueueLow.async {
print("低:\(Thread.current)")
}
serialQueueHigh.async {
print("高:\(Thread.current)")
self.ended()
}
自动执行任务组
// Swift2.3
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
let concurrentQueue: dispatch_queue_t = getConcurrentQueue("cn.zeluli")
let group: dispatch_group_t = dispatch_group_create()
//将group与queue进行管理,并且自动执行
for i in 1...3 {
dispatch_group_async(group, concurrentQueue) {
currentThreadSleep(1)
print("任务\(i)执行完毕\n")
}
}
//队列组的都执行完毕后会进行通知
dispatch_group_notify(group, dispatch_get_main_queue()) {
print("所有的任务组执行完毕!\n")
}
print("异步执行测试,不会阻塞当前线程")
}
// Swift3.0
DispatchQueue.global(qos: .default).async {
let concurrentQueue = DispatchQueue(label: "cn.zeluli", attributes: .concurrent)
let group = DispatchGroup()
//将group与queue进行管理,并且自动执行
for i in 1...3 {
concurrentQueue.async(group: group) {
self.currentThreadSleep(1)
print("任务\(i)执行完毕\n")
}
}
//队列组的都执行完毕后会进行通知
group.notify(queue: DispatchQueue.main) {
self.ended()
}
print("异步执行测试,不会阻塞当前线程")
}
手动执行任务组
// Swift2.3
let concurrentQueue: dispatch_queue_t = dispatch_queue_create("cn.zeluli", DISPATCH_QUEUE_CONCURRENT)
let group: dispatch_group_t = dispatch_group_create()
//将group与queue进行手动关联和管理,并且自动执行
for i in 1...3 {
dispatch_group_enter(group) //进入队列组
dispatch_async(concurrentQueue, {
currentThreadSleep(1)
print("任务\(i)执行完毕\n")
dispatch_group_leave(group) //离开队列组
})
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER) //阻塞当前线程,直到所有任务执行完毕
print("任务组执行完毕")
dispatch_group_notify(group, concurrentQueue) {
print("手动管理的队列执行OK")
}
// Swift3.0
let concurrentQueue = DispatchQueue(label: "cn.zeluli", attributes: .concurrent)
let group = DispatchGroup()
//将group与queue进行手动关联和管理,并且自动执行
for i in 1...3 {
group.enter() //进入队列组
concurrentQueue.async {
self.currentThreadSleep(1)
print("任务\(i.toEmoji)执行完毕\n")
group.leave() //离开队列组
}
}
_ = group.wait(timeout: .distantFuture) //阻塞当前线程,直到所有任务执行完毕
print("任务组执行完毕")
group.notify(queue: concurrentQueue) {
self.ended()
}
使用信号量添加同步锁
// Swift2.3
func useSemaphoreLock() {
let concurrentQueue = getConcurrentQueue("cn.zeluli")
//创建信号量
let semaphoreLock: dispatch_semaphore_t = dispatch_semaphore_create(1)
var testNumber = 0
for index in 1...10 {
dispatch_async(concurrentQueue, {
dispatch_semaphore_wait(semaphoreLock, DISPATCH_TIME_FOREVER) //上锁
testNumber += 1
currentThreadSleep(Double(1))
print(getCurrentThread())
print("第\(index)次执行: testNumber = \(testNumber)\n")
dispatch_semaphore_signal(semaphoreLock) //开锁
})
}
print("异步执行测试\n")
}
// Swift3.0
func useSemaphoreLock() {
let concurrentQueue = getConcurrentQueue("cn.zeluli")
//创建信号量
let semaphoreLock = DispatchSemaphore(value: 1)
var testNumber = 0
for index in 0...9 {
concurrentQueue.async {
let wait = semaphoreLock.wait(timeout: .distantFuture) //上锁
print("wait=\(wait)")
testNumber += 1
self.currentThreadSleep(1)
print(Thread.current)
print("第\(index.toEmoji)次执行: testNumber = \(testNumber)\n")
semaphoreLock.signal() //开锁
}
}
}
使用Apply循环执行
// Swift2.3
func useDispatchApply() {
print("循环多次执行并行队列")
let concurrentQueue: dispatch_queue_t = getConcurrentQueue("cn.zeluli")
//会阻塞当前线程, 但concurrentQueue队列会在新的线程中执行
dispatch_apply(3, concurrentQueue) { (index) in
currentThreadSleep(Double(index))
print("第\(index)次执行,\n\(getCurrentThread())\n")
}
print("\n\n循环多次执行串行队列")
let serialQueue: dispatch_queue_t = getSerialQueue("cn.zeluli")
//会阻塞当前线程, serialQueue队列在当前线程中执行
dispatch_apply(3, serialQueue) { (index) in
currentThreadSleep(Double(index))
print("第\(index)次执行,\n\(getCurrentThread())\n")
}
}
// Swift3.0
/// 循环执行
func useDispatchApply() {
print("循环多次执行并行队列")
DispatchQueue.concurrentPerform(iterations: 3) { (index) in
currentThreadSleep(Double(index))
print("第\(index)次执行,\n\(Thread.current)\n")
}
ended()
}
暂停和重启队列
// Swift2.3
func queueSuspendAndResume() {
let concurrentQueue = getConcurrentQueue("cn.zeluli")
dispatch_suspend(concurrentQueue) //将队列进行挂起
dispatch_async(concurrentQueue) {
print("任务执行")
}
currentThreadSleep(2)
dispatch_resume(concurrentQueue) //将挂起的队列进行唤醒
}
// Swift3.0
func queueSuspendAndResume() {
let concurrentQueue = getConcurrentQueue("cn.zeluli")
concurrentQueue.suspend() //将队列进行挂起
concurrentQueue.async {
print("任务执行, \(Thread.current)")
}
currentThreadSleep(2)
concurrentQueue.resume() //将挂起的队列进行唤醒
ended()
}
使用任务隔离栅栏(这个东西可以用来处理经典的数组异步读写问题)
// Swift2.3
func useBarrierAsync() {
let concurrentQueue: dispatch_queue_t = getConcurrentQueue("cn.zeluli")
for i in 0...3 {
dispatch_async(concurrentQueue) {
currentThreadSleep(Double(i))
print("第一批:\(i)\(getCurrentThread())")
}
}
dispatch_barrier_async(concurrentQueue) {
print("\n第一批执行完毕后才会执行第二批\n\(getCurrentThread())\n")
}
for i in 0...3 {
dispatch_async(concurrentQueue) {
currentThreadSleep(Double(i))
print("第二批:\(i)\(getCurrentThread())")
}
}
print("异步执行测试\n")
}
// Swift3.0
func useBarrierAsync() {
let concurrentQueue = getConcurrentQueue("cn.zeluli")
for i in 0...3 {
concurrentQueue.async {
self.currentThreadSleep(Double(i))
print("第一批:\(i.toEmoji)\(Thread.current)")
}
}
let workItem = DispatchWorkItem(flags: .barrier) {
print("\n第一批执行完毕后才会执行第二批\n\(Thread.current)\n")
}
concurrentQueue.async(execute: workItem)
for i in 0...3 {
concurrentQueue.async {
self.currentThreadSleep(Double(i))
print("第二批:\(i.toEmoji)\(Thread.current)")
}
}
print("😁😁😁不会阻塞主线程😁😁😁")
}
DispatchSource
// Swift2.3
/**
以加法运算的方式合并数据
*/
func useDispatchSourceAdd() {
var sum = 0 //手动计数的sum, 来模拟记录merge的数据
let queue = getGlobalQueue()
//创建source
let dispatchSource:dispatch_source_t = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, queue)
dispatch_source_set_event_handler(dispatchSource) {
print("source中所有的数相加的和等于\(dispatch_source_get_data(dispatchSource))")
print("sum = \(sum)\n")
sum = 0
currentThreadSleep(0.3)
}
dispatch_resume(dispatchSource)
for i in 1...10 {
sum += i
print(i)
dispatch_source_merge_data(dispatchSource, UInt(i))
currentThreadSleep(0.1)
}
}
/**
以或运算的方式合并数据
*/
func useDispatchSourceOr() {
var or = 0 //手动计数的sum, 来记录merge的数据
let queue = getGlobalQueue()
//创建source
let dispatchSource:dispatch_source_t = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_OR, 0, 0, queue)
dispatch_source_set_event_handler(dispatchSource) {
print("source中所有的数相加的和等于\(dispatch_source_get_data(dispatchSource))")
print("or = \(or)\n")
or = 0
currentThreadSleep(0.3)
}
dispatch_resume(dispatchSource)
for i in 1...10 {
or |= i
print(i)
dispatch_source_merge_data(dispatchSource, UInt(i))
currentThreadSleep(0.1)
}
print("\nsum = \(or)")
}
/**
使用dispatch_source创建定时器
*/
func useDispatchSourceTimer() {
let queue: dispatch_queue_t = getGlobalQueue()
let source: dispatch_source_t = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue)
//设置间隔时间,从当前时间开始,允许偏差0纳秒
dispatch_source_set_timer(source, DISPATCH_TIME_NOW, UInt64(1 * NSEC_PER_SEC), 0)
var timeout = 10 //倒计时时间
//设置要处理的事件, 在我们上面创建的queue队列中进行执行
dispatch_source_set_event_handler(source) {
print(getCurrentThread())
if(timeout <= 0) {
dispatch_source_cancel(source)
} else {
print("\(timeout)s")
timeout -= 1
}
}
//倒计时结束的事件
dispatch_source_set_cancel_handler(source) {
print("倒计时结束")
}
dispatch_resume(source)
}
// Swift3.0
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px 'PingFang SC'; color: #4dbf56}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #526eda}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #ffffff}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #4dbf56}p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #ffffff; min-height: 21.0px}p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #93c96a}p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #00afca}span.s1 {font: 18.0px Menlo; font-variant-ligatures: no-common-ligatures}span.s2 {font-variant-ligatures: no-common-ligatures}span.s3 {font-variant-ligatures: no-common-ligatures; color: #ffffff}span.s4 {font-variant-ligatures: no-common-ligatures; color: #4dbf56}span.s5 {font-variant-ligatures: no-common-ligatures; color: #526eda}span.s6 {font-variant-ligatures: no-common-ligatures; color: #c2349b}span.s7 {font-variant-ligatures: no-common-ligatures; color: #8b84cf}span.s8 {font: 18.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures}span.s9 {font-variant-ligatures: no-common-ligatures; color: #93c96a}span.s10 {font-variant-ligatures: no-common-ligatures; color: #00afca}span.s11 {font-variant-ligatures: no-common-ligatures; color: #e44347}span.s12 {font: 18.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures; color: #e44347}span.s13 {font: 18.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #ffffff}span.s14 {font: 18.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures; color: #4dbf56}
/// 以加法运算的方式合并数据
// http://www.tanhao.me/pieces/360.html/
func useDispatchSourceAdd() {
var sum = 0 //手动计数的sum, 来模拟记录merge的数据
let queue = getGlobalQueue()
//创建source
let dispatchSource = DispatchSource.makeUserDataAddSource(queue: queue)
dispatchSource.setEventHandler() {
print("source中所有的数相加的和等于\(dispatchSource.data)")
print("sum = \(sum)\n")
sum = 0
self.currentThreadSleep(0.3)
}
// DispatchQueue启动时默认状态是挂起的,创建完毕之后得主动恢复,否则事件不会被传送
dispatchSource.resume()
for i in 1...10 {
sum += i
print("i=\(i)")
dispatchSource.add(data: UInt(i))
currentThreadSleep(0.1)
}
ended()
}
/// 以或运算的方式合并数据
func useDispatchSourceOr() {
var or = 0 //手动计数的sum, 来记录merge的数据
let queue = getGlobalQueue()
//创建source
let dispatchSource = DispatchSource.makeUserDataOrSource(queue: queue)
dispatchSource.setEventHandler {
print("source中所有的数相加的和等于\(dispatchSource.data)")
print("or = \(or)\n")
or = 0
self.currentThreadSleep(0.3)
}
dispatchSource.resume()
for i in 1...10 {
or |= i
print("i=\(i)")
dispatchSource.or(data: UInt(i))
currentThreadSleep(0.1)
}
print("\nsum = \(or)")
}
/// 使用DispatchSource创建定时器
func useDispatchSourceTimer() {
let queue = getGlobalQueue()
let source = DispatchSource.makeTimerSource(queue: queue)
// deadline 结束时间
// interval 时间间隔
// leeway 时间精度
source.scheduleRepeating(deadline: .now(), interval: 1, leeway: .nanoseconds(0))
var timeout = 10 //倒计时时间
//设置要处理的事件, 在我们上面创建的queue队列中进行执行
source.setEventHandler {
print(Thread.current)
if(timeout <= 0) {
source.cancel()
} else {
print("\(timeout)s", Date())
timeout -= 1
}
}
//倒计时结束的事件
source.setCancelHandler {
print("倒计时结束")
}
source.resume()
}