当前位置: 首页 > 面试题库 >

在Swift 3,Swift 4及更高版本中,我该如何使用dispatch_sync,dispatch_async,dispatch_after等?

爱唯
2023-03-14
问题内容

我在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(测试版)中打开了我的项目,就会遇到各种各样的错误。其中一些提供了修复我的代码的功能,但并非所有修复都可以产生有效的代码。我该怎么办?


问题答案:

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

在Xcode 8 / Swift 3 beta中,Apple应用了此功能(以及其他一些功能)来使Dispatch框架更加迅速。(还有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常量之一。服务质量(QoS)说明符是在OS X
10.10 / iOS
8.0中引入的,它为系统确定工作的优先级和弃用旧优先级说明符提供了更清晰的方法。有关详细信息,请参阅Apple的有关后台工作和能源效率的文档。

顺便说一句,如果您要保留自己的队列来组织工作,那么现在就可以这样获得通知(注意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中打开新的Dispatch API的界面来找到自己的出路-
使用“快速打开”找到Dispatch模块,或DispatchQueue在您的Swift项目/操场中放一个符号(如)并单击鼠标,然后在其中浏览从那里的模块。(您可以在Apple新颖的API参考网站和in-
Xcode文档查看器中找到Swift Dispatch
API,但看来C版本的文档内容尚未移入其中。)

有关更多提示,请参见《迁移指南》。



 类似资料:
  • 在Swift 2中,我能够使用延迟使用中央调度的操作: 但自Swift3以来,这似乎不再编译了。用现代Swift写这篇文章的首选方式是什么?

  • 问题内容: 在我的代码中,我有一个简单的for循环,使用嵌套的for循环循环100次以创建延迟。延迟之后,我将通过dispatch_async更新UI中的进度视图元素。但是,我无法更新UI。有谁知道为什么用户界面没有更新?注意:下面的print语句用于验证for循环是否正确循环。 问题答案: 三种观察,两种基本观察,一种更为先进: 除非循环本身在另一个线程上运行,否则循环将无法更新该主线程中的UI

  • 我正在编写一个教会应用程序,其中我正在使用本教程使用可滑动的选项卡 但我希望我的应用程序支持Froyo及以上! AndroidManifest.xml

  • 我有一个在eclipse上运行的项目,但当我制作“java-jar”时,它会出现以下错误: 当我制作“java-version”时,输出是: 我做错了什么?

  • 问题内容: 更新: 为了保存PDF文件: 在下面的答案部分。 为了保存位图文件: 问题答案: 在Android 10及更高版本中保存PDF文件:

  • 问题内容: 我正在使用python 3.5.1,它带有3.8.11的sqlite版本。我想知道我是否可以在当前的python中使用其他版本的sqlite(例如到目前为止的最新版本)。如果答案是肯定的,那我该怎么做?从这里学习,我尝试了这个,但是它什么也没做: 我在需要全文搜索的django项目中使用sqlite3。因此,我正在阅读本文档,并在某种程度上使我 倾向于 使用最新版本的sqlite3,因