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测试版中,苹果应用了这个功能(以及其他一些功能),使Dispatch框架更加Swifty。(还有Core Graphics。)如果你一直在关注Swift开源的努力,这不是新闻,但这是它第一次成为Xcode的一部分。
将任何项目移动到Swift 3的第一步应该是在Xcode 8中打开它,并选择编辑>将>转换为当前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)说明符,为系统提供了一种更清晰的方式来对工作进行优先级划分,并弃用了旧的优先级说明符。详情请参阅苹果公司的背景工作和能源效率文件。
顺便说一下,如果你保持你自己的队列来组织工作,现在获得一个队列的方式看起来像这样(注意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,它有各种数字类型的操作符,所以你可以只添加整秒或小数秒:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { // in half a second...
print("Are we there yet?")
}
你可以通过在Xcode 8中打开它的接口来找到新的分派API——使用“快速打开”来找到分派模块,或者在你的Swift项目/操场上放一个符号(比如DispatchQueue),然后命令点击它,然后从那里浏览模块。(你可以在苹果漂亮的新API参考网站和xcode文档查看器中找到Swift Dispatch API,但看起来C版本的文档内容还没有移动到它中。)
有关更多技巧,请参阅迁移指南。