说明

Swift中的操作是一种强大的方法,可以在跟踪进度和依赖项的同时将职责划分为多个类。它们的正式名称为NSOperations,并与结合使用OperationQueue。

确保首先阅读我在Swift中关于并发的文章 ,这样您就知道队列和调度的基础知识。操作与调度块有很多共同点,但还有更多好处。让我们开始吧!

Swift中的Operation是什么?

操作通常负责单个同步任务。这是一个抽象类,从未直接使用过。您可以使用系统定义的BlockOperation子类或通过创建自己的子类。您可以通过将操作添加到OperationQueue或手动调用start方法来启动操作。但是,强烈建议您全权负责OperationQueue管理状态。

使用系统定义的BlockOperation外观如下:

let blockOperation = BlockOperation {print("Executing!")
}let queue = OperationQueue()
queue.addOperation(blockOperation)

也可以通过直接在队列上添加块来完成:

queue.addOperation {print("Executing!")
}

给定的任务将添加到中OperationQueue,该任务将尽快开始执行。

创建自定义操作

您可以使用自定义操作创建关注点分离。例如,您可以创建一个用于导入内容的自定义实现,以及一个用于上载内容的自定义实现。

以下代码示例显示了用于导入内容的自定义子类:

final class ContentImportOperation: Operation {let itemProvider: NSItemProviderinit(itemProvider: NSItemProvider) {self.itemProvider = itemProvidersuper.init()}override func main() {guard !isCancelled else { return }print("Importing content..")// .. import the content using the item provider}
}

该类接受项目提供程序,并在main方法中导入内容。该main()函数是同步操作唯一需要覆盖的方法。将操作添加到队列,并设置完成块以跟踪完成:

let fileURL = URL(fileURLWithPath: "..")
let contentImportOperation = ContentImportOperation(itemProvider: NSItemProvider(contentsOf: fileURL)!)contentImportOperation.completionBlock = {print("Importing completed!")
}queue.addOperation(contentImportOperation)// Prints:
// Importing content..
// Importing completed!

这将所有将内容导入到单个类中的逻辑转移到了一个类上,您可以在该类上跟踪进度,完成情况,并且可以轻松为此编写测试!

操作的不同状态

一个操作可以根据当前执行状态处于几种状态。

  • Ready: 准备开始
  • Executing: 任务当前正在运行
  • Finished: 流程完成后
  • Canceled: 任务已取消

重要的是要知道一个操作只能执行一次。无论何时处于完成或取消状态,您都无法再重新启动同一实例。

在自定义实现中,您需要在执行之前手动检查已取消状态,以确保任务已取消。是否知道在同时开始和取消操作时会发生数据争用。您可以在我的博客文章Thread Sanitizer解释中详细了解数据竞赛 :Swift中的数据竞赛。

在OperationQueue一旦成为完成,这两个执行或取消后会自动从队列中删除该任务。

利用依赖

仅在内容导入完成后才开始上传。它没有考虑取消,这意味着如果取消导入操作,上传仍将开始。您必须执行检查以查看依赖关系是否已取消:

final class UploadContentOperation: Operation {override func main() {guard !dependencies.contains(where: { $0.isCancelled }), !isCancelled else {return}print("Uploading content..")}
}

使用操作的好处是使用依赖项。您可以轻松地在两个实例之间添加依赖项。例如,要在导入内容后开始上传:

let fileURL = URL(fileURLWithPath: "..")
let contentImportOperation = ContentImportOperation(itemProvider: NSItemProvider(contentsOf: fileURL)!)
contentImportOperation.completionBlock = {print("Importing completed!")
}let contentUploadOperation = UploadContentOperation()
contentUploadOperation.addDependency(contentImportOperation)
contentUploadOperation.completionBlock = {print("Uploading completed!")
}queue.addOperations([contentImportOperation, contentUploadOperation], waitUntilFinished: true)// Prints:
// Importing content..
// Uploading content..
// Importing completed!
// Uploading completed!

结论

希望您对开始在Swift中实现操作感到兴奋。这是一个隐藏的瑰宝,可让您分离问题,在任务之间添加依赖关系并跟踪完成情况。

这篇文章是系列文章的一部分:

  1. Swift中的Operations和OperationQueues入门(本文)
  2. 在Swift中编写并发解决方案的异步操作
  3. 通过使用泛型进行高级异步操作

也可以以Swift Playground的形式找到:https : //github.com/AvdLee/AsyncOperations

如果您想进一步提高Swift知识,请查看 Swift类别页面。随意 与我联系 或鸣叫我在 Twitter的 ,如果您有任何额外的提示或反馈。

谢谢!

参考

https://www.avanderlee.com/swift/operations/

翻译:Swift中的Operations和OperationQueues入门相关推荐

  1. Swift中的函数curring简介

    When you hear the word "curry", the very first thing that probably passes through your min ...

  2. swift建立桥接_在Swift中建立Alexa技能

    swift建立桥接 by Claus Höfele 通过克劳斯·霍费尔 在Swift中建立Alexa技能 (Building Alexa Skills in Swift) 如何使用Swift开发Ama ...

  3. swift 引用swift_Swift Swift中的单元测试:基础知识

    swift 引用swift In this first part of the Unit Testing in Swift series, we will cover how to add a uni ...

  4. [译] Swift 中的动态特性

    原文地址:Dynamic Features in Swift 原文作者:Mike Finney 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m- 译者:iWesli ...

  5. 探索 Swift 中的 MVC-N 模式

    作者:Marcus Zarra(twitter:@mzarra) Marcus 将会为大家介绍一种设计模式,他曾经在那些需要从互联网进行大量频繁数据请求的 iOS 应用当中使用此设计模式.这个设计采用 ...

  6. 怎样在swift中创建CocoaPods

    本文由yake_099(博客)翻译自raywenderlich,作者:Joshua Greene 原文:How to Create CocoaPods with Swift 你可能对一些比较著名的开源 ...

  7. Swift中编写单例的正确方式

    本文由CocoaChina译者leon(社区ID)翻译自krakendev 原文:THE RIGHT WAY TO WRITE A SINGLETON 转载请保持所有内容和链接的完整性. 在之前的帖子 ...

  8. swift设置启动图不现实_如何通过装饰房屋来开始在Swift中使用增强现实

    swift设置启动图不现实 by Ranadhir Dey 由Ranadhir Dey 如何通过装饰房屋来开始在Swift中使用增强现实 (How to get started with augmen ...

  9. swift视图容器_如何使用IBDesignable在Swift中创建漂亮的,可重复使用的渐变视图...

    swift视图容器 by Lee Dowthwaite 通过李道思韦特 如何使用IBDesignable在Swift中创建漂亮的,可重复使用的渐变视图 (How to create a beautif ...

  10. 在 Swift 中使用闭包实现懒加载

    本文讲的是在 Swift 中使用闭包实现懒加载, 原文地址:Swift Lazy Initialization with Closures 原文作者:Bob Lee 译文出自:掘金翻译计划 译者:ls ...

最新文章

  1. 面试官:如何做 API 接口防刷??
  2. 深入理解 Java 虚拟机(第一弹) - Java 内存区域透彻分析
  3. 3ds max 变形器使用
  4. 【c语言】蓝桥杯算法训练 斜率计算
  5. opencv图像特征检测之斑点检测
  6. ios消息推送机制原理与实现(转)
  7. python编写脚本方法_python 定时器,实现每天凌晨3点执行的方法
  8. 【STM32】修改芯片型号后报 Error 的解决方案
  9. 06 SQL执行计划
  10. MATLAB获取字符串中两个特定字符之间的内容
  11. 通过vba代码将excel转换为PDF
  12. ipv6一致性测试(IPv6 Specification)内核修改
  13. WiFi 2.4G和5G国家及信道分布
  14. layim php,PHP版layim整合融云简单实现
  15. Visual Studio中的Android模拟器使用详解
  16. 【环境配置】gazebo搭建仿真机器人研究动态障碍物算法
  17. 环境工程部门怎么实施自动化软件学习时间更多
  18. 快速理解数据库超键,候选键,主键
  19. 7-5 最佳情侣身高差c语言
  20. 装机不求人,10 分钟电脑配置挑选速成攻略

热门文章

  1. java 获取class的方法_[Java教程]Java反射定义、获取Class三种方法
  2. XMLHttpReq.onreadystatechange 传递参数
  3. 动态规划——Palindrome Partitioning II
  4. 读书笔记之深入理解Java虚拟机
  5. maven解决“Could not calculate build plan”问题
  6. Maven入门指南12:将项目发布到私服
  7. rownum与order by
  8. http服务器和application服务器区别
  9. C#对IE使用Proxy(代理)
  10. Windows 编程[6] - 学习窗体生成的过程六: 最终的代码!