此项目已停止维护。
现在不仅仅是 Swift 中 Grand Central Dispatch (GCD) 异步调度的语法糖了
Async 语法糖看起来像这样
Async.userInitiated {
10
}.background {
"Score: \($0)"
}.main {
label.text = $0
}
即使 Swift 3.0 之后的 GCD 已经有了相对不错的语法,请将上面的代码与下面进行比较:
DispatchQueue.global(qos: .userInitiated).async {
let value = 10
DispatchQueue.global(qos: .background).async {
let text = "Score: \(value)"
DispatchQueue.main.async {
label.text = text
}
}
}
AsyncGroup 语法糖看起来像这样
let group = AsyncGroup()
group.background {
print("This is run on the background queue")
}
group.background {
print("This is also run on the background queue in parallel")
}
group.wait()
print("Both asynchronous blocks are complete")
File > Swift Packages > Add Package Dependency (文件 > Swift Packages > 添加 Package 依赖)
dependencies: [
.package(url: "https://github.com/duemunk/Async", from: "2.1.0"),
],
use_frameworks!
pod "AsyncSwift"
github "duemunk/Async"
支持现代队列类
Async.main {}
Async.userInteractive {}
Async.userInitiated {}
Async.utility {}
Async.background {}
随意链式调用任意数量的 block
Async.userInitiated {
// 1
}.main {
// 2
}.background {
// 3
}.main {
// 4
}
存储引用以便后续链式调用
let backgroundBlock = Async.background {
print("This is run on the background queue")
}
// Run other code here...
// Chain to reference
backgroundBlock.main {
print("This is run on the \(qos_class_self().description) (expected \(qos_class_main().description)), after the previous block")
}
自定义队列
let customQueue = DispatchQueue(label: "CustomQueueLabel", attributes: [.concurrent])
let otherCustomQueue = DispatchQueue(label: "OtherCustomQueueLabel")
Async.custom(queue: customQueue) {
print("Custom queue")
}.custom(queue: otherCustomQueue) {
print("Other custom queue")
}
延迟调度 block
let seconds = 0.5
Async.main(after: seconds) {
print("Is called after 0.5 seconds")
}.background(after: 0.4) {
print("At least 0.4 seconds after previous block, and 0.9 after Async code is called")
}
取消尚未调度的 block
// Cancel blocks not yet dispatched
let block1 = Async.background {
// Heavy work
for i in 0...1000 {
print("A \(i)")
}
}
let block2 = block1.background {
print("B – shouldn't be reached, since cancelled")
}
Async.main {
// Cancel async to allow block1 to begin
block1.cancel() // First block is _not_ cancelled
block2.cancel() // Second block _is_ cancelled
}
等待 block 完成 – 一种在后台任务完成后在当前队列上继续执行的简便方法
let block = Async.background {
// Do stuff
}
// Do other stuff
block.wait()
它的工作方式是使用 OS X 10.10 和 iOS 8 中引入的 GCD 的新通知 API。每个链式 block 都在前一个队列完成后被调用。
let previousBlock = {}
let chainingBlock = {}
let dispatchQueueForChainingBlock = ...
// Use the GCD API to extend the blocks
let _previousBlock = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, previousBlock)
let _chainingBlock = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, chainingBlock)
// Use the GCD API to call back when finishing the "previous" block
dispatch_block_notify(_previousBlock, dispatchQueueForChainingBlock, _chainingBlock)
链式调用的语法部分是通过在 Async
对象上拥有类方法来实现的,例如 Async.main {}
,它返回一个结构体。该结构体具有匹配的方法,例如 theStruct.main {}
。
现代 GCD 队列在 iOS 模拟器中无法按预期工作。请参阅问题 13, 22。
dispatch_block_t
无法扩展。解决方法:将 dispatch_block_t
包装在一个结构体中,该结构体将 block 作为属性。
还有一个用于 dispatch_apply()
的包装器,用于快速并行化 for
循环。
Apply.background(100) { i in
// Do stuff e.g. print(i)
}
请注意,此函数在 block 运行 100 次后返回,即它不是异步的。对于异步行为,请将其包装在 Async
block 中,例如 Async.background { Apply.background(100) { ... } }
。
AsyncGroup 方便处理异步 block 组。
使用 GCD 的多个调度 block
let group = AsyncGroup()
group.background {
// Run on background queue
}
group.utility {
// Run on utility queue, in parallel to the previous block
}
group.wait()
所有现代队列类
group.main {}
group.userInteractive {}
group.userInitiated {}
group.utility {}
group.background {}
自定义队列
let customQueue = dispatch_queue_create("Label", DISPATCH_QUEUE_CONCURRENT)
group.custom(queue: customQueue) {}
等待组完成
let group = AsyncGroup()
group.background {
// Do stuff
}
group.background {
// Do other stuff in parallel
}
// Wait for both to finish
group.wait()
// Do rest of stuff
自定义异步操作
let group = AsyncGroup()
group.enter()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
// Do stuff
group.leave()
}
group.enter()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
// Do other stuff in parallel
group.leave()
}
// Wait for both to finish
group.wait()
// Do rest of stuff
The MIT License (MIT)
Copyright (c) 2016 Tobias Due Munk
特此授予任何人免费获得本软件及相关文档文件(“软件”)副本的许可,以不受限制地处理本软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本的权利,并允许向其提供本软件的人员遵守以下条件
以上版权声明和本许可声明应包含在本软件的所有副本或重要部分中。
本软件按“原样”提供,不提供任何形式的明示或暗示保证,包括但不限于对适销性、特定用途适用性和不侵权的保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论是在合同、侵权或其他方面,因本软件或本软件的使用或与本软件有关的其他交易而引起、产生或与之相关的责任。