OperationPlus
OperationPlus 是一套针对 的子类和扩展,它旨在填补 API 中的缺失部分。您无需学习任何新内容即可使用它。
有多个替代方案可以用于 NSOperation 模型,最著名的就是 Combine。但是,Combine 相对较新,并且仅适用于最新的操作系统版本。Apple 已经发布了 NSOperation 几年,并且广泛使用。一旦您开始针对它构建实际应用,您可能会发现 API 缺少了某些重要的组成部分。OperationPlus 尝试使事物更方便和可组合。
整合
Swift 包管理器
dependencies: [
.package(url: "https://github.com/ChimeHQ/OperationPlus.git")
]
Carthage
github "ChimeHQ/OperationPlus"
CocoaPods
pod 'OperationPlus'
NSOperation 子类
BaseOperation
:提供核心功能,以便于NSOperation
的子类化AsyncOperation
:用于异步支持的BaseOperation
的便利包装器AsyncBlockOperation
:用于内联异步支持的便利类(Async)ProducerOperation
:生成输出(Async)ConsumerOperation
:从ProducerOperation
接受输入(Async)ConsumerProducerOperation
:从ProducerOperation
接受输入并生成输出
BaseOperation
这是一个简单易扩展的 NSOperation
子类。它具有以下特点
- 线程安全
- 超时支持
- 更简单的取消处理
- 更严格的状态检查
- 内置的异步支持
- 简便的自定义
let a = BaseOperation(timeout: 5.0)
// NSOperation will happily allow you do this even
// if `a` has finished. `BaseOperation` will not.
a.addDependency(another)
// ...
public override func main() {
// This will return true if your operation is cancelled, timed out,
// or prematurely finished. ProducerOperation subclass state will be
// handled correctly as well.
if self.checkForCancellation() {
return
}
}
// ...
AsyncOperation
一个可用于您异步操作的 BaseOperation
子类。这些操作需要延长它们的生命周期超出 main
方法。
import Foundation
import OperationPlus
class MyAsyncOperation: AsyncOperation {
public override func main() {
DispatchQueue.global().async {
if self.checkForCancellation() {
return
}
// do stuff
self.finish()
}
}
}
此类没有任何特别之处——只是为了方便。如果您愿意,可以直接继承 BaseOperation
并重写一个方法。
import Foundation
import OperationPlus
class MyAsyncOperation: BaseOperation {
override open var isAsynchronous: Bool {
return true
}
}
ProducerOperation
一个 BaseOperation
子类,能产生值。包括一个完成处理程序以访问该值。
import Foundation
import OperationPlus
class MyValueOperation: ProducerOperation<Int> {
public override func main() {
// do your computation
self.finish(with: 42)
}
}
// ...
let op = MyValueOperation()
op.resultCompletionBlock = { (value) in
// use value here
}
AsyncProducerOperation
ProducerOperation
的一个变体,主方法执行完成后可能产生值。
import Foundation
import OperationPlus
class MyAsyncOperation: AsyncProducerOperation<Int> {
public override func main() {
DispatchQueue.global().async {
if self.checkForCancellation() {
return
}
// do stuff
self.finish(with: 42)
}
}
}
ConsumerOperation 和 AsyncConsumerOperation
一个接受 ProducerOperation
输入的 BaseOperation
子类。
import Foundation
import OperationPlus
class MyConsumerOperation: ConsumerOperation<Int> {
override func main() {
guard let value = producerValue else {
// handle failure in some way
}
}
override func main(with value: Int) {
// make use of value here, or automatically
// fail if it wasn't successfully produced
}
}
let op = MyConsumerOperation(producerOp: myIntProducerOperation)
AsyncBlockOperation
对 NSBlockOperation
的戏仿,但使得在不创建 Operation
子类的情况下可能实现异步完成。非常适合快速、内联的工作。
let op = AsyncBlockOperation { (completionBlock) in
DispatchQueue.global().async {
// do some async work here, just be certain to call
// the completionBlock when done
completionBlock()
}
}
NSOperation/NSOperationQueue 扩展
队列创建方便
let a = OperationQueue(name: "myqueue")
let b = OperationQueue(name: "myqueue", maxConcurrentOperations: 1)
let c = OperationQueue.serialQueue()
let d = OperationQueue.serialQueue(named: "myqueue")
强制执行运行时队列执行约束
OperationQueue.preconditionMain()
OperationQueue.preconditionNotMain()
简洁的依赖关系
queue.addOperation(op, dependency: opA)
queue.addOperation(op, dependencies: [opA, opB])
queue.addOperation(op, dependencies: Set([opA, opB]))
op.addDependencies([opA, opB])
op.addDependencies(Set([opA, opB]))
在队列的当前操作完成后排队工作
queue.currentOperationsFinished {
print("all pending ops done")
}
方便的内联函数
queue.addAsyncOperation { (completionHandler) in
DispatchQueue.global().async {
// do some async work
completionHandler()
}
}
延时
queue.addOperation(op, afterDelay: 5.0)
queue.addOperation(afterDelay: 5.0) {
// work
}
XCTest 支持
OperationTestingPlus 是一个可选的微型框架,可以帮助使您的基于 XCTest 的测试更加友好。当使用 Carthage 时,它被构建为一个静态框架,以帮助简化与您的测试目标的集成。
FulfillExpectationOperation
当操作完成时,一个简单的 NSOperation 将满足 XCTestExpectation
。与您其他操作的依赖关系一起使用时非常有用。
NeverFinishingOperation
测试您的 Operations 超时行为的绝佳方法。
OperationExpectation
一个 XCTestExpectation
子类,可以使测试异步操作更加类似于 XCTest。
let op = NeverFinishingOperation()
let expectation = OperationExpectation(operation: op)
expectation.isInverted = true
wait(for: [expectation], timeout: 1.0)
建议或反馈
我们非常乐意听取您的意见!请通过 twitter、问题或拉取请求与我们联系。
请注意,此项目使用 贡献者行为准则 发布。通过参与此项目,您同意遵守其条款。