【问题标题】:GCD differences in Swift 3Swift 3 中的 GCD 差异
【发布时间】:2016-10-04 11:28:27
【问题描述】:

当我注意到 Swift 3 改变了它的语法时,我正在研究 Grand Central Dispatch

那么,是这样的吗:

let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

    dispatch_async(queue) { () -> Void in

        let img1 = Downloader.downloadImageWithURL(imageURLs[0])

        dispatch_async(dispatch_get_main_queue(), {

            self.imageView1.image = img1
        })   
    }

和这个有什么不同吗?

DispatchQueue.global(qos: .default).async { [weak self]

            () -> Void in

            let img1 = Downloader.downloadImageWithURL(imageURLs[0])

            DispatchQueue.main.async {

                ()->Void in

                self?.imageView1.image = img1
            }

        }

我应该创建一个变量来包含DispatchQueue.global(qos: .default).async吗?

【问题讨论】:

    标签: ios swift concurrency grand-central-dispatch


    【解决方案1】:

    Swift 3 对 Grand Central Dispatch 的语法和用法进行了许多改进。

    以前,我们会选择分派方法(同步与异步),然后选择我们想要分派任务的队列。更新后的 GCD 颠倒了这个顺序——我们首先选择队列,然后应用调度方法。

    DispatchQueue.global(attributes: [.qosDefault]).async { 
        // Background thread
        DispatchQueue.main.async(execute: { 
            // UI Updates
        })
    }
    

    队列属性

    您会注意到队列现在在 init 上具有属性。这是一个 Swift 选项集,可以包括队列选项,例如串行与并发、内存和活动管理选项以及服务质量(.default、.userInteractive、.userInitiated、.utility 和 .background)。 服务质量取代了 iOS8 中已弃用的旧优先级属性。如果您习惯了优先级队列,以下是它们如何映射到 QOS 案例:

    * DISPATCH_QUEUE_PRIORITY_HIGH:         .userInitiated
    * DISPATCH_QUEUE_PRIORITY_DEFAULT:      .default
    * DISPATCH_QUEUE_PRIORITY_LOW:          .utility
    * DISPATCH_QUEUE_PRIORITY_BACKGROUND:   .background
    

    工作项目

    队列并不是 GCD 中唯一获得 Swift OptionSet 的部分。工作项也有更新的 Swift 语法:

    let workItem = DispatchWorkItem(qos: .userInitiated, flags: .assignCurrentContext) {
        // Do stuff
    }
    queue.async(execute: workItem)
    

    工作项现在可以在初始化时声明质量或服务和/或标志。这两个都是可选的,会影响工作项的执行。

    dispatch_once

    dispatch_once 对于初始化代码和其他只执行一次的函数非常有用。 在 Swift 3 中,dispatch_once 已被弃用,应替换为全局或静态变量和常量。

    // Examples of dispatch_once replacements with global or static constants and variables. 
    // In all three, the initialiser is called only once. 
    
    // Static properties (useful for singletons).
    class Object {
        static let sharedInstance = Object()
    }
    
    // Global constant.
    let constant = Object()
    
    // Global variable.
    var variable: Object = {
        let variable = Object()
        variable.doSomething()
        return variable
    }()
    

    dispatch_assert

    今年 Apple OS 版本中的另一个新功能是调度先决条件。这些替换 dispatch_assert 并允许您在执行代码之前检查您是否在预期的线程上。这对于更新 UI 并且必须在主队列上执行的函数特别有用。这是一个简单的例子:

    let queue = DispatchQueue.global(attributes: .qosUserInitiated)
    let mainQueue = DispatchQueue.main
    
    mainQueue.async {
        dispatchPrecondition(condition: .notOnQueue(mainQueue))
        // This code won't execute
    }
    
    queue.async {
        dispatchPrecondition(condition: .onQueue(queue))
        // This code will execute
    }
    

    来源:https://medium.com/swift-and-ios-writing/a-quick-look-at-gcd-and-swift-3-732bef6e1838#.7hdtfwxb4

    【讨论】:

      【解决方案2】:

      除了在第一种方法中没有弱化self之外,两个调用都是等价的。

      是否创建变量取决于您的(方便)偏好,并且在技术上没有区别。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-24
        • 2017-01-27
        • 1970-01-01
        • 2017-04-04
        • 2015-08-04
        • 2018-03-10
        相关资源
        最近更新 更多