翻译:Swift中的Operations和OperationQueues入门
说明
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中实现操作感到兴奋。这是一个隐藏的瑰宝,可让您分离问题,在任务之间添加依赖关系并跟踪完成情况。
这篇文章是系列文章的一部分:
- Swift中的Operations和OperationQueues入门(本文)
- 在Swift中编写并发解决方案的异步操作
- 通过使用泛型进行高级异步操作
也可以以Swift Playground的形式找到:https : //github.com/AvdLee/AsyncOperations
如果您想进一步提高Swift知识,请查看 Swift类别页面。随意 与我联系 或鸣叫我在 Twitter的 ,如果您有任何额外的提示或反馈。
谢谢!
参考
https://www.avanderlee.com/swift/operations/
翻译:Swift中的Operations和OperationQueues入门相关推荐
- Swift中的函数curring简介
When you hear the word "curry", the very first thing that probably passes through your min ...
- swift建立桥接_在Swift中建立Alexa技能
swift建立桥接 by Claus Höfele 通过克劳斯·霍费尔 在Swift中建立Alexa技能 (Building Alexa Skills in Swift) 如何使用Swift开发Ama ...
- 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 ...
- [译] Swift 中的动态特性
原文地址:Dynamic Features in Swift 原文作者:Mike Finney 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m- 译者:iWesli ...
- 探索 Swift 中的 MVC-N 模式
作者:Marcus Zarra(twitter:@mzarra) Marcus 将会为大家介绍一种设计模式,他曾经在那些需要从互联网进行大量频繁数据请求的 iOS 应用当中使用此设计模式.这个设计采用 ...
- 怎样在swift中创建CocoaPods
本文由yake_099(博客)翻译自raywenderlich,作者:Joshua Greene 原文:How to Create CocoaPods with Swift 你可能对一些比较著名的开源 ...
- Swift中编写单例的正确方式
本文由CocoaChina译者leon(社区ID)翻译自krakendev 原文:THE RIGHT WAY TO WRITE A SINGLETON 转载请保持所有内容和链接的完整性. 在之前的帖子 ...
- swift设置启动图不现实_如何通过装饰房屋来开始在Swift中使用增强现实
swift设置启动图不现实 by Ranadhir Dey 由Ranadhir Dey 如何通过装饰房屋来开始在Swift中使用增强现实 (How to get started with augmen ...
- swift视图容器_如何使用IBDesignable在Swift中创建漂亮的,可重复使用的渐变视图...
swift视图容器 by Lee Dowthwaite 通过李道思韦特 如何使用IBDesignable在Swift中创建漂亮的,可重复使用的渐变视图 (How to create a beautif ...
- 在 Swift 中使用闭包实现懒加载
本文讲的是在 Swift 中使用闭包实现懒加载, 原文地址:Swift Lazy Initialization with Closures 原文作者:Bob Lee 译文出自:掘金翻译计划 译者:ls ...
最新文章
- 面试官:如何做 API 接口防刷??
- 深入理解 Java 虚拟机(第一弹) - Java 内存区域透彻分析
- 3ds max 变形器使用
- 【c语言】蓝桥杯算法训练 斜率计算
- opencv图像特征检测之斑点检测
- ios消息推送机制原理与实现(转)
- python编写脚本方法_python 定时器,实现每天凌晨3点执行的方法
- 【STM32】修改芯片型号后报 Error 的解决方案
- 06 SQL执行计划
- MATLAB获取字符串中两个特定字符之间的内容
- 通过vba代码将excel转换为PDF
- ipv6一致性测试(IPv6 Specification)内核修改
- WiFi 2.4G和5G国家及信道分布
- layim php,PHP版layim整合融云简单实现
- Visual Studio中的Android模拟器使用详解
- 【环境配置】gazebo搭建仿真机器人研究动态障碍物算法
- 环境工程部门怎么实施自动化软件学习时间更多
- 快速理解数据库超键,候选键,主键
- 7-5 最佳情侣身高差c语言
- 装机不求人,10 分钟电脑配置挑选速成攻略
热门文章
- java 获取class的方法_[Java教程]Java反射定义、获取Class三种方法
- XMLHttpReq.onreadystatechange 传递参数
- 动态规划——Palindrome Partitioning II
- 读书笔记之深入理解Java虚拟机
- maven解决“Could not calculate build plan”问题
- Maven入门指南12:将项目发布到私服
- rownum与order by
- http服务器和application服务器区别
- C#对IE使用Proxy(代理)
- Windows 编程[6] - 学习窗体生成的过程六: 最终的代码!