我如何在Swift 3,Swift 4及之后的dispatch_sync,dispatch_async,dispatch_after等?

我在Swift 2.x(甚至1.x)项目中有很多代码,看起来像这样:

// Move to a background thread to do some long running work dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { let image = self.loadOrGenerateAnImage() // Bounce back to the main thread to update the UI dispatch_async(dispatch_get_main_queue()) { self.imageView.image = image } } 

或者像这样的东西来延迟执行:

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.5 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { print("test") } 

或者Grand Central Dispatch API的各种其他用途…

现在,我已经在Swift 3的Xcode 8(beta)中打开了我的项目,我得到了各种各样的错误。 其中一些提供修复我的代码,但不是所有的修复产生工作代码。 HALP! 我该怎么做?

从一开始,Swift就提供了一些使ObjC和C更加Swifty的设施,每个版本都增加了更多的function。 现在,在Swift 3中,新的“作为成员导入”function可以让具有特定风格的C API的框架 – 其中有一种类似于类的数据types,以及一系列全局函数来处理它 -更像Swift本地API。 数据types导入为Swift类,其相关的全局函数作为这些类的方法和属性导入,在适当的情况下,一些相关的东西(如常量集合)可以成为子types。

在Xcode 8 / Swift 3testing版中,苹果已经应用了这个function(以及其他一些function),使得调度框架更加Swifty。 (和Core Graphics也是如此。)如果你一直在关注Swift的开源工作, 这不是什么新闻 ,但是现在是它第一次成为Xcode的一部分。

将任何项目移动到Swift 3的第一步应该是在Xcode 8中打开它,然后在菜单中select“ 编辑”>“转换”>“到当前Swift语法… ”。 这将适用于(通过您的审查和批准)所有重新命名的API和其他更改所需的所有更改。 (通常,一行代码同时受到多个这些更改的影响,因此,对错误修复进行响应 – 它个别地可能无法处理所有事情。)

其结果是,反弹工作的背景和背面的常见模式现在看起来像这样:

 // Move to a background thread to do some long running work DispatchQueue.global(qos: .userInitiated).async { let image = self.loadOrGenerateAnImage() // Bounce back to the main thread to update the UI DispatchQueue.main.async { self.imageView.image = image } } 

请注意,我们正在使用.userInitiated而不是旧的DISPATCH_QUEUE_PRIORITY常量之一。 在OS X 10.10 / iOS 8.0中引入了服务质量(QoS)说明符,为系统提供了一个更清晰的方式来区分工作的优先级和弃用旧的优先级说明符。 有关详细信息,请参阅有关后台工作和能源效率的 Apple 文档 。

顺便说一句,如果你保持自己的队列来组织工作,现在得到一个方法看起来像这样(注意DispatchQueueAttributes是一个OptionSet ,所以你使用集合风格文字来组合选项):

 class Foo { let queue = DispatchQueue(label: "com.example.my-serial-queue", attributes: [.serial, .qosUtility]) func doStuff() { queue.async { print("Hello World") } } } 

dispatch_after稍后做工作? 这也是一个队列方法,它需要一个DispatchTime ,它有各种数字types的运算符,所以你可以添加整个或小数秒:

 DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { // in half a second... print("Are we there yet?") } 

你可以通过在Xcode 8中打开它的接口来find你的方法 – 使用Open Quickly来查找Dispatch模块,或者在你的Swift项目/游乐场中放置一个符号(比如DispatchQueue ),然后命令单击它,然后驱动从那里模块周围。 (您可以在苹果新的API参考网站和in-Xcode文档查看器中findSwift Dispatch API,但是看起来来自C版本的文档内容还没有移入它。)

有关更多提示,请参阅“ 迁移指南” 。

在Xcode 8testing版4不起作用..使用:

 DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { print("Are we there yet?") } 

为asynchronous两种方式:

 DispatchQueue.main.async { print("Async1") } DispatchQueue.main.async( execute: { print("Async2") }) 

在xcode8中使用:

 DispatchQueue.global(qos: .userInitiated).async { } 

这是Swift 3关于async好例子:

 DispatchQueue.global(qos: .background).async { // Background Thread DispatchQueue.main.async { // Run UI Updates } } 

斯威夫特4

主要和背景队列

 let main = DispatchQueue.main let background = DispatchQueue.global() let helper = DispatchQueue(label: "another_thread") 

使用asynchronous和同步线程!

  background.async { //async tasks here } background.sync { //sync tasks here } 

asynchronous线程将与主线程一起工作。

同步线程将在执行时阻塞主线程。