Queuer 2.1.1

Queuer 2.1.1

测试已测试
Lang语言 SwiftSwift
许可 MIT
发布最新发布2019年11月
SPM支持SPM

Fabrizio Brancati维护。




Queuer 2.1.1

Queuer Banner

Build Status Coverage Status Documentation Swift Package Manager Compatible Carthage Compatible Version License
Maintainability codebeat badge Language Platforms


特性需求安装使用文档更新日志沟通贡献作者许可


特性

Queuer是一个队列管理器,基于OperationQueueDispatch(也称为GCD)构建。
它允许您轻松创建任何异步和同步任务,所有任务都由一个队列管理,只需几行代码。

以下是所有特性的列表

  • 在所有兼容Swift的平台(甚至Linux)上运行
  • 易于使用
  • 文档齐全(100%文档化)
  • 测试良好(100%代码覆盖率)
  • 创建一个操作块
  • 创建单个操作
  • 创建链式操作
  • 管理集中式队列
  • 创建无限队列
  • 声明队列可以处理多少并发操作
  • 创建信号量
  • 创建和处理计划
  • 自动或手动重试操作
  • 恢复未完成操作的能力
  • 改进状态恢复特性
  • 在每次自动重试操作之间的节流
  • OperationQueue中每个操作都可以访问的数据层

需求

Swift Xcode Queuer iOS macOS tvOS watchOS Linux
3.1...3.2 8.3...9.0 1.0.0...1.1.0 8.0+ 10.10+ 9.0+ 2.0+ ✓
4.0 9.0...9.2 1.3.0 8.0+ 10.10+ 9.0+ 2.0+ ✓
4.1 9.3...9.4 1.3.1...1.3.2 8.0+ 10.10+ 9.0+ 2.0+ ✓
4.2 10.0...10.1 2.0.0...2.0.1 8.0+ 10.10+ 9.0+ 3.0+ ✓
5.0...5.1 10.2...11.2 2.1.0...2.1.1 8.0+ 10.10+ 9.0+ 3.0+ ✓

安装

查看需求部分,检查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")

您甚至可以通过定义 maxConcurrentOperationCountqualityOfService 属性来创建队列

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)

我们稍后将看到 ConcurrentOperationSynchronousOperation 的用法。

链式操作

链式操作是相互增加依赖的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()

    为了有一个完整的pauseresume状态,您必须创建一个覆盖了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设置为truefalse,让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),如:nameprogressdependencies
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 文件。