在Swift 3,Swift 4及更高版本中,我该如何使用dispatch_sync,dispatch_async,dispatch_after等? [英] How do I dispatch_sync, dispatch_async, dispatch_after, etc in Swift 3, Swift 4, and beyond?

查看:208
本文介绍了在Swift 3,Swift 4及更高版本中,我该如何使用dispatch_sync,dispatch_async,dispatch_after等?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Swift 2.x(甚至1.x)项目中有很多代码,如下所示:

I have lots of code in Swift 2.x (or even 1.x) projects that looks like this:

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

或类似这样的东西会延迟执行:

Or stuff like this to delay execution:

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

或Grand Central Dispatch API的所有其他各种用途...

Or any of all kinds of other uses of the Grand Central Dispatch API...

现在,我已经在Swift 3的Xcode 8(测试版)中打开了我的项目,我遇到了各种各样的错误.其中一些提供了修复我的代码的功能,但并非所有修复都可以产生有效的代码.我该怎么办?

Now that I've opened my project in Xcode 8 (beta) for Swift 3, I get all kinds of errors. Some of them offer to fix my code, but not all of the fixes produce working code. What do I do about this?

推荐答案

从一开始,Swift就提供了一些使ObjC和C更加Swifty的功能,每个版本都增加了更多功能.现在,在Swift 3中,新的导入为成员" 功能使具有某些C API样式的框架(在其中您具有类似类的数据类型,并具有许多与其一起使用的全局函数)可以更像Swift-本机API.数据类型作为Swift类导入,它们的相关全局函数作为这些类上的方法和属性导入,并且某些相关的东西(如常量集)可以在适当的时候成为子类型.

Since the beginning, Swift has provided some facilities for making ObjC and C more Swifty, adding more with each version. Now, in Swift 3, the new "import as member" feature lets frameworks with certain styles of C API -- where you have a data type that works sort of like a class, and a bunch of global functions to work with it -- act more like Swift-native APIs. The data types import as Swift classes, their related global functions import as methods and properties on those classes, and some related things like sets of constants can become subtypes where appropriate.

在Xcode 8/Swift 3 beta中,Apple应用了此功能(以及其他一些功能)来使Dispatch框架变得更加Swifty. (还有核心图形.)如果您一直在关注Swift开源工作, 这不是新闻 ,但这是它第一次成为Xcode的一部分.

In Xcode 8 / Swift 3 beta, Apple has applied this feature (along with a few others) to make the Dispatch framework much more Swifty. (And Core Graphics, too.) If you've been following the Swift open-source efforts, this isn't news, but now is the first time it's part of Xcode.

将任何项目移至Swift 3的第一步应该是在Xcode 8中将其打开,然后在菜单中选择 Edit> Convert> To Current Swift Syntax ... .菜单.这将适用于所有已重命名的API所需的所有更改(并需要您的审核和批准),以及其他更改. (通常,一行代码一次会受到多个更改的影响,因此单独对错误修复进行响应-可能无法正确处理所有错误.)

Your first step on moving any project to Swift 3 should be to open it in Xcode 8 and choose Edit > Convert > To Current Swift Syntax... in the menu. This will apply (with your review and approval) all of the changes at once needed for all the renamed APIs and other changes. (Often, a line of code is affected by more than one of these changes at once, so responding to error fix-its individually might not handle everything right.)

结果是,现在将工作弹跳到背景和背景的常见模式如下:

The result is that the common pattern for bouncing work to the background and back now looks like this:

// 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常量之一.服务质量(QoS)说明符是在OS X 10.10/iOS 8.0中引入的,它为系统确定工作的优先级和弃用旧优先级说明符提供了更清晰的方法.请参阅Apple的有关后台工作和能源效率的文档以获取详细信息.

Note we're using .userInitiated instead of one of the old DISPATCH_QUEUE_PRIORITY constants. Quality of Service (QoS) specifiers were introduced in OS X 10.10 / iOS 8.0, providing a clearer way for the system to prioritize work and deprecating the old priority specifiers. See Apple's docs on background work and energy efficiency for details.

顺便说一句,如果您要保留自己的队列来组织工作,则现在的获取方式如下所示(请注意,DispatchQueueAttributesOptionSet,因此您可以使用集合样式的文字来组合选项):

By the way, if you're keeping your own queues to organize work, the way to get one now looks like this (notice that DispatchQueueAttributes is an OptionSet, so you use collection-style literals to combine options):

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

使用dispatch_after稍后再工作?这也是在队列上的一种方法,它需要DispatchTime,它具有用于各种数值类型的运算符,因此您可以将整秒或小数秒相加:

Using dispatch_after to do work later? That's a method on queues, too, and it takes a DispatchTime, which has operators for various numeric types so you can just add whole or fractional seconds:

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

您可以通过在Xcode 8中打开新的Dispatch API界面来找到自己的方式-使用快速打开"查找Dispatch模块,或在Swift项目/操场中放置符号(如DispatchQueue),并使用以下命令-单击它,然后从那里浏览模块. (您可以在Apple新颖的API参考网站和In-Xcode文档查看器中找到Swift Dispatch API. ,但看来C版本的文档内容尚未移入其中.)

You can find your way around the new Dispatch API by opening its interface in Xcode 8 -- use Open Quickly to find the Dispatch module, or put a symbol (like DispatchQueue) in your Swift project/playground and command-click it, then brouse around the module from there. (You can find the Swift Dispatch API in Apple's spiffy new API Reference website and in-Xcode doc viewer, but it looks like the doc content from the C version hasn't moved into it just yet.)

有关更多提示,请参见迁移指南.

See the Migration Guide for more tips.

这篇关于在Swift 3,Swift 4及更高版本中,我该如何使用dispatch_sync,dispatch_async,dispatch_after等?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆