我在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")
}

或是中央调度API的任何其他用途...

现在我已经在Swift 3的Xcode 8(beta版)中打开了我的项目,我遇到了各种各样的错误.他们中的一些人提供修复我的代码,但并不是所有的修复都能产生工作代码.我该怎么办?

推荐答案

从一开始,Swift就提供了一些设施,使ObjC和C更快捷,每个版本都增加了更多功能.现在,在Swift 3中,新的"import as member"特性让具有特定风格的C API的框架(其中有一种工作方式类似于类的数据类型,以及一系列全局函数)更像Swift原生API.数据类型作为Swift类导入,它们相关的全局函数作为这些类上的方法和属性导入,一些相关的东西,如常量集,可以在适当的情况下成为子类型.

在Xcode 8/Swift 3测试版中,苹果应用了这一功能(以及其他一些功能),使调度框架更加快速.(还有Core Graphics个.)如果你一直在关注Swift的开源工作,this isn't news,但现在是第一次它是Xcode的一部分.

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.)

结果是,将工作反弹到背景并返回的常见模式现在如下所示:

// 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)说明符,为系统提供了一种更清晰的方式来划分工作优先级,并摒弃了旧的优先级说明符.详见苹果docs on background work and energy efficiency强.

顺便说一句,如果您要保留自己的队列来组织工作,那么现在获得一个队列的方式是这样的(请注意,DispatchQueueAttributesOptionSet,所以您使用集合样式的文字来组合选项):

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

dispatch_after块钱以后再做工作?这也是队列上的一种方法,它需要DispatchTime,它有各种数字类型的运算符,所以你可以只添加整秒或分数秒:

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

您可以通过在Xcode 8中打开新的调度API的接口来找到解决方法——使用Open Quick查找调度模块,或者在Swift项目/playground 中放置一个符号(如DispatchQueue),然后单击它,然后从那里浏览该模块.(你可以在苹果新的API参考网站和Xcode doc viewer中找到Swift Dispatch API,但看起来C版本的文档内容还没有进入.)

更多提示请参见Migration Guide.

Swift相关问答推荐

SwiftUI—如何识别单词并获取视觉中的位置

SWIFT:使字典数组值可变

在MacOS上检测键盘是否有Globe键

';NSInternal不一致异常';,原因:';可见导航栏Xcode 15.0 Crash请求布局

在扩展中创建通用排序函数

Swift 包管理器 Package.resolved 文件末尾的版本是什么意思?

为什么在Swift中每次调用Decimal类型的formatted()方法都会越来越慢?

MainActor 隔离可变存储属性为何会出现可发送错误?

如果 Swift 无法分配内存会怎样?

如何从 LLDB 调用带有断点的 Swift 函数?

What is "SwiftPM.SPMRepositoryError error 5"?

在 Swift 中强制崩溃的最简单方法

自定义 MKAnnotation 标注视图?

两个 Date 对象之间的所有日期 (Swift)

如何在 Swift 中重写 setter

在 xcode8 中找不到 ModuleName-Swift.h 文件

Objective-C 方法与可选需求方法 Swift 冲突

在情节提要中设置的 UITableViewCell 的恢复 ID 和标识符有什么区别

Swift - 要求实现协议的类是某个类的子类

UITableView 布局在 push segue 和 return 上搞砸了. (iOS 8、Xcode beta 5、Swift)