OperationPlus 1.5.2

OperationPlus 1.5.2

Matt Massicotte 维护。



Github CI Carthage compatible CocoaPods CocoaPods

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)
        }
    }
}

ConsumerOperationAsyncConsumerOperation

一个接受 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、问题或拉取请求与我们联系。

请注意,此项目使用 贡献者行为准则 发布。通过参与此项目,您同意遵守其条款。