Queuer 是一个队列管理器,构建于 OperationQueue 和 Dispatch (又名 GCD) 之上。 它允许您轻松创建任何异步和同步任务,所有这些都由队列管理,只需几行代码即可。
以下是所有功能的列表
Swift | Queuer | iOS | macOS | macCatalyst | tvOS | watchOS | visionOS | Linux |
---|---|---|---|---|---|---|---|---|
3.1...3.2 | 1.0.0...1.1.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ✅ | ||
4.0 | 1.3.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ✅ | ||
4.1 | 1.3.1...1.3.2 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ✅ | ||
4.2 | 2.0.0...2.0.1 | 8.0+ | 10.10+ | 9.0+ | 3.0+ | ✅ | ||
5.0...5.10 | 2.1.0...2.2.0 | 8.0+ | 10.10+ | 9.0+ | 3.0+ | ✅ | ||
5.9...5.10 | 3.0.0 | 12.0+ | 10.13+ | 13.0+ | 12.0+ | 4.0+ | 1.0+ | ✅ |
请参阅 Requirements 部分以检查 Swift、Queuer 和 OS 版本。
在您的 Package.swift
Swift Package Manager 清单中,将以下依赖项添加到您的 dependencies
参数
.package(url: "https://github.com/FabrizioBrancati/Queuer.git", from: "3.0.0"),
将依赖项添加到您在清单中声明的任何目标
.target(
name: "MyTarget",
dependencies: [
.product(name: "Queuer", package: "Queuer"),
]
),
Queuer 提供了一个共享实例,您可以使用它将操作添加到中心化队列
Queuer.shared.addOperation(operation)
您还可以创建一个自定义队列
let queue = Queuer(name: "MyCustomQueue")
您甚至可以通过定义 maxConcurrentOperationCount
和 qualityOfService
属性来创建队列
let queue = Queuer(name: "MyCustomQueue", maxConcurrentOperationCount: Int.max, qualityOfService: .default)
您有三种方法可以添加 Operation
块。
直接在 queue
(或 Queuer.shared
)上
queue.addOperation {
/// Your task here
}
使用块创建一个 ConcurrentOperation
let concurrentOperation = ConcurrentOperation { _ in
/// Your task here
}
queue.addOperation(concurrentOperation)
注意
我们稍后会看到 ConcurrentOperation
的工作原理。
链式操作是相互添加依赖关系的 Operation
。
它们遵循给定的数组顺序,例如: [A, B, C] = A -> B -> C -> completionBlock
。
let concurrentOperationA = ConcurrentOperation { _ in
/// Your task A here
}
let concurrentOperationB = ConcurrentOperation { _ in
/// Your task B here
}
queue.addChainedOperations([concurrentOperationA, concurrentOperationB]) {
/// Your completion task here
}
您还可以在队列创建后添加一个 completionHandler
,使用
queue.addCompletionHandler {
/// Your completion task here
}
组操作是处理一组带有完成处理程序的 Operation
的 Operation
。
允许执行一组带有完成处理程序的 Operation
,该完成处理程序将在所有操作完成后调用,例如: [A -> [[B & C & D] -> completionHandler] -> E] -> completionHandler
。 它通常应与 Chained Opetation 一起使用。
let groupOperationA = GroupOperation(
[
ConcurrentOperation { _ in
/// Your task A here
},
ConcurrentOperation { _ in
/// Your task B here
}
]
)
let concurrentOperationC = ConcurrentOperation { _ in
/// Your task C here
}
queue.addChainedOperations([groupOperationA, concurrentOperationC]) {
/// Your completion task here
}
在这种情况下,输出将如下所示: [[A & B -> completionHandler] -> C] -> completionHandler
。
有几种方法可以处理队列状态。
取消队列中的所有 Operation
queue.cancelAll()
暂停队列
queue.pause()
警告
通过调用 pause()
,您不能确定每个 Operation
都会被暂停。 如果 Operation
已经启动,则在它是覆盖 pause()
函数的自定义 Operation
之前,它不会暂停。
恢复队列
queue.resume()
警告
要获得完整的 pause
和 resume
状态,您必须创建一个覆盖 pause()
和 resume()
函数的自定义 Operation
。
等待直到所有 Operation
完成
queue.waitUntilAllOperationsAreFinished()
重要
此函数意味着队列将阻塞当前线程,直到所有 Operation
完成。
将队列的 maxConcurrentOperationCount
属性设置为 1
将确保一次只执行一个任务。
ConcurrentOperation
是一个被创建用于被子类化的类。 它允许同步和异步任务,具有暂停和恢复状态,可以轻松添加到队列,并且可以使用块创建。
您可以通过子类化来创建您的自定义 ConcurrentOperation
。
您必须覆盖 execute()
函数,并在任务完成其工作以通知队列时,在其中调用 finish(success:)
函数。
为方便起见,它有一个带有完成块的 init
函数
let concurrentOperation = ConcurrentOperation { _ in
/// Your task here
}
concurrentOperation.addToQueue(queue)
一个 Operation
被传递给每个闭包,通过它您可以设置和处理重试功能。
默认情况下,重试功能被禁用,要启用它,只需将 success
属性设置为 false
。 success
为 false
时,Operation
将重试,直到达到 maximumRetries
属性值。 为了让 Operation
知道何时一切正常,您必须将 success
设置为 true
。
通过 currentAttempt
,您可以知道 Operation
处于哪个尝试次数。
let concurrentOperation = ConcurrentOperation { operation in
/// Your task here
if /* Successful */ {
operation.success = true
} else {
operation.success = false
}
}
当您认为执行会成功时,您可以手动重试 Operation
。
一个 Operation
被传递给每个闭包,通过它您可以设置和处理重试功能。
默认情况下,手动重试功能被禁用,要启用它,只需将 manualRetry
属性设置为 true
,您必须在执行闭包之外执行此操作。 您还必须将 success
设置为 true
或 false
,以让 Operation
知道何时一切正常,就像自动重试功能一样。
要让 Operation
重试您的执行闭包,您必须调用 retry()
函数。 确保至少调用 maximumRetries
次,如果您调用 retry()
的次数多于需要的次数,则没有问题,您的执行闭包将不会执行超过 maximumRetries
值的次数。
let concurrentOperation = ConcurrentOperation { operation in
/// Your task here
if /* Successful */ {
operation.success = true
} else {
operation.success = false
}
}
concurrentOperation.manualRetry = true
/// Later on your code
concurrentOperation.retry()
注意
如果未调用 retry()
函数,您可能会阻塞整个队列。
默认情况下,Operation
将在执行闭包完成时完成其工作。
这意味着,如果您的闭包中有一个异步任务,Operation
将在任务完成之前完成。
如果您想手动完成它,您可以将 manualFinish
属性设置为 true
,并在任务完成时调用 finish(success:)
函数。
使用 success
参数将 finish(success:)
函数调用为 true
或 false
,以让 Operation
知道任务是否成功。 如果您没有显式设置 success
参数,它将被设置为 true
。
let concurrentOperation = ConcurrentOperation { operation in
/// Your asynchonous task here
}
concurrentOperation.manualFinish = true
/// Later on your code in your asynchronous task
concurrentOperation.finish(success: true)
注意
如果您不调用 finish(success:)
函数,您的队列将被阻塞,并且永远不会结束。
如果您想使用 async/await 任务,您需要将 manualFinish
设置为 true
,以便完全控制 Operation
生命周期。
注意
阅读更多关于手动完成 Operation
的信息 这里。
let concurrentOperation = ConcurrentOperation { operation in
Task {
/// Your asynchonous task here
operation.finish(success: true) // or false
}
/// Your asynchonous task here
}
concurrentOperation.manualFinish = true
注意
如果您不将 manualFinish
设置为 true
,您的 Operation
将在异步任务完成之前完成。
Scheduler
是一个结构体,它使用 GDC 的 DispatchSourceTimer
来创建一个定时器,该定时器可以使用指定的间隔和服务质量执行函数。
let schedule = Scheduler(deadline: .now(), repeating: .seconds(1)) {
/// Your task here
}
您甚至可以在没有处理程序的情况下创建一个 Scheduler
,稍后再设置它
var schedule = Scheduler(deadline: .now(), repeating: .seconds(1))
schedule.setHandler {
/// Your task here
}
通过 timer
属性,您可以访问所有 DispatchSourceTimer
属性和函数,例如 cancel()
schedule.timer.cancel()
Semaphore
是一个结构体,它使用 GCD 的 DispatchSemaphore
在函数上创建一个信号量,并等待它完成其工作。
提示
建议在 Semaphore
创建和 wait()
调用之后立即使用 defer { semaphore.continue() }
。
let semaphore = Semaphore()
semaphore.wait()
defer { semaphore.continue() }
/// Your task here
您甚至可以设置自定义超时,默认为 .distantFuture
semaphore.wait(DispatchTime(uptimeNanoseconds: 1_000_000_000))
如果在异步任务中使用它会更有用
let concurrentOperation = ConcurrentOperation {
/// Your task here
semaphore.continue()
}
concurrentOperation.addToQueue(queue)
semaphore.wait()
要查看 Queuer 最近版本中的更改,请参阅 CHANGELOG.md 文件。
请参阅 CONTRIBUTING.md 文件。
Queuer 在 MIT 许可证下可用。 有关更多信息,请参阅 LICENSE 文件。