特性 • 需求 • 安装 • 使用 • 文档 • 更新日志 • 沟通 • 贡献 • 作者 • 许可
特性
Queuer是一个队列管理器,基于OperationQueue和Dispatch(也称为GCD)构建。
它允许您轻松创建任何异步和同步任务,所有任务都由一个队列管理,只需几行代码。
以下是所有特性的列表
- 在所有兼容Swift的平台(甚至Linux)上运行
- 易于使用
- 文档齐全(100%文档化)
- 测试良好(100%代码覆盖率)
- 创建一个操作块
- 创建单个操作
- 创建链式操作
- 管理集中式队列
- 创建无限队列
- 声明队列可以处理多少并发操作
- 创建信号量
- 创建和处理计划
- 自动或手动重试操作
- 恢复未完成操作的能力
- 改进状态恢复特性
- 在每次自动重试操作之间的节流
OperationQueue
中每个操作都可以访问的数据层
需求
安装
查看需求部分,检查Swift、Xcode、Queuer和操作系统版本。
手动安装
- 打开并从项目(Queuer.xcodeproj)构建框架
- 将Queuer.framework导入到你的项目中
- 使用
import Queuer
导入框架 - 享受吧!
CocoaPods
-
在你的项目目录中创建一个Podfile并写入以下内容:
platform :ios, '8.0' xcodeproj 'Project.xcodeproj' use_frameworks! pod 'Queuer'
-
将"Project"替换为你的实际项目名称
-
打开终端,转到你的项目目录,并输入:
pod install
-
使用
import Queuer
导入框架 -
享受吧!
Carthage
-
在你的项目目录中创建一个Cartfile并写入以下内容:
github "FabrizioBrancati/Queuer"
-
打开终端,转到项目目录,并输入:
carthage update
-
将创建的框架包含到你的项目中
-
添加构建阶段,内容如下
/usr/local/bin/carthage copy-frameworks
在输入文件下添加Queuer框架的路径
$(SRCROOT)/Carthage/Build/iOS/Queuer.framework
在输出文件中添加复制的框架的路径
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Queuer.framework
此脚本通过绕过由通用二进制引起的App Store提交错误,确保在存档时复制必要的位码相关文件
-
(可选) 添加构建阶段,内容如下
/usr/local/bin/carthage outdated --xcode-warnings
自动警告你当你的一个依赖项过时
-
使用
import Queuer
导入框架 -
享受吧!
Swift 包管理器
-
在你的项目目录中创建一个 Package.swift 文件,并写入以下内容:
// swift-tools-version:5.1 import PackageDescription let package = Package( name: "Project", products: [ .executable(name: "Project", targets: ["Project"]) ], dependencies: [ .package(url: "https://github.com/FabrizioBrancati/Queuer.git", .upToNextMajor(from: "2.0.0")) ], targets: [ .target(name: "Project", dependencies: ["Queuer"]) ] )
-
将"Project"替换为你的实际项目名称
-
打开 终端,转到项目目录并输入:
swift build
-
使用
import 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)
-
使用代码块创建一个
SynchronousOperation
let synchronousOperation = SynchronousOperation { _ in /// Your task here } queue.addOperation(synchronousOperation)
我们稍后将看到
ConcurrentOperation
和SynchronousOperation
的用法。
链式操作
链式操作是相互增加依赖的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
。queue.cancelAll()
-
暂停队列。
queue.pause()
通过调用
pause()
,您无法确定每个Operation
都会被暂停。
如果Operation
已经启动,它将不会暂停,直到它是一个覆盖了pause()
函数的自定义Operation
。 -
恢复队列。
queue.resume()
为了有一个完整的
pause
和resume
状态,您必须创建一个覆盖了pause()
和resume()
函数的自定义Operation
。 -
等待所有
Operation
完成。queue.waitUntilAllOperationsAreFinished()
这个函数意味着队列会阻塞当前线程,直到所有
Operation
都完成。
异步操作
ConcurrentOperation
是一个创建用来继承的类。它允许同步和异步任务,有暂停和恢复状态,可以很方便地添加到队列中,并可以使用代码块创建。
您可以通过继承它来创建自己的ConcurrentOperation
。
您必须覆盖execute()
函数,并在其中调用finish()
函数来通知队列任务完成。
为了方便,它有一个包含完成块的init
函数。
let concurrentOperation = ConcurrentOperation { _ in
/// Your task here
}
concurrentOperation.addToQueue(queue)
同步操作
有三种方法创建同步任务,甚至队列:
- 将队列的
maxConcurrentOperationCount
设置为1
。
通过将该属性设置为1
,您将确保每次只执行一个任务。 - 使用一个
信号量
,等待任务完成其工作。 - 使用
同步操作
。
它是并发操作
的一个子类,用于处理同步任务。
看似很酷,但实际上创建异步任务总是更好,但有时这可能很有用。
为了方便,它有一个包含完成块的init
函数。
let synchronousOperation = SynchronousOperation { _ in
/// Your task here
}
synchronousOperation.addToQueue(queue)
自动重试操作
将一个操作
传递给每一个闭包,你可以通过它来设置和处理重试功能。
默认情况下重试功能是禁用的,要启用它,只需将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
}
}
手动重试操作
当你认为执行将成功时,可以手动重试一个操作
。
将一个操作
传递给每一个闭包,你可以通过它来设置和处理重试功能。
默认情况下手动重试功能是禁用的,要启用它,只需将manualRetry
属性设置为true
,你必须在执行闭包之外这样做。你还必须将success
设置为true
或false
,让Operation
知道何时一切正常,就像自动重试功能一样。
要让Operation
重试你的执行闭包,你必须调用retry()
函数。如果未调用retry()
,可能会导致整个队列阻塞。确保至少调用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()
调度器
调度器
是一个结构体,它使用GDC的DispatchSourceTimer
创建定时器,该定时器可以以指定的间隔和服务质量执行函数。
let schedule = Scheduler(deadline: .now(), repeating: .seconds(1)) {
/// Your task here
}
甚至可以在没有处理程序的情况下创建一个调度器
,然后稍后设置它。
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()
队列状态恢复(Beta)
要启用队列恢复功能,您必须使用具有唯一(非 nil)name
属性的 ConcurrentOperation
。目前此功能允许您保存队列的当前状态(OperationState
),如:name
、progress
和 dependencies
。progress
属性允许保存 Operation
进度的当前状态。在 Operation
执行过程中,请持续更新它。
调用 Queuer.state(of: OperationQueue)
或 operationQueue.state()
来获取 QueueStateList
,即:OperationState
的数组。
保存和检索此列表以及正确创建队列取决于您。
文档
Jazzy 生成 文档 - 100% 文档化
变更日志
要查看 Queuer 近期版本中的变化,请参阅 CHANGELOG.md 文件。
通信
- 如果您需要帮助,请打开一个 issue。
- 如果您发现了错误,请打开一个 issue。
- 如果您有功能请求,请打开一个 issue。
- 如果您想做出贡献,请参阅 贡献 部分。
贡献
参见 CONTRIBUTING.md 文件。
作者
Fabrizio Brancati
网站: https://www.fabriziobrancati.com
邮箱: [email protected]
许可协议
Queuer 在 MIT 许可协议下提供。有关更多信息,请参阅 LICENSE 文件。