414

在 Swift 2 中,我可以使用以下代码创建队列:

let concurrentQueue = dispatch_queue_create("com.swift3.imageQueue", DISPATCH_QUEUE_CONCURRENT)

但这不能在 Swift 3 中编译。

在 Swift 3 中编写这个的首选方法是什么?

4

15 回答 15

1166

创建并发队列

let concurrentQueue = DispatchQueue(label: "queuename", attributes: .concurrent)
concurrentQueue.sync {

}  

创建串行队列

let serialQueue = DispatchQueue(label: "queuename")
serialQueue.sync { 

}

异步获取主队列

DispatchQueue.main.async {

}

同步获取主队列

DispatchQueue.main.sync {

}

获取后台线程之一

DispatchQueue.global(qos: .background).async {

}

Xcode 8.2 测试版 2:

获取后台线程之一

DispatchQueue.global(qos: .default).async {

}

DispatchQueue.global().async {
    // qos' default value is ´DispatchQoS.QoSClass.default`
}

如果您想了解如何使用这些队列。请参阅此答案

于 2016-06-14T08:15:32.470 回答
56

在 >= Swift 3下编译。这个例子包含了我们需要的大部分语法。

QoS - 新的服务质量语法

weak self- 破坏保留周期

如果 self 不可用,则什么也不做

async global utility queue- 对于网络查询,不等待结果,它是一个并发队列,块(通常)在启动时不等待。并发队列的例外可能是,当先前已达到其任务限制时,该队列会暂时变为串行队列并等待该队列中的某个先前任务完成。

async main queue- 对于触摸 UI,块不等待结果,而是在开始时等待它的插槽。主队列是串行队列。

当然,您需要为此添加一些错误检查...

DispatchQueue.global(qos: .utility).async { [weak self] () -> Void in

    guard let strongSelf = self else { return }

    strongSelf.flickrPhoto.loadLargeImage { loadedFlickrPhoto, error in

        if error != nil {
            print("error:\(error)")
        } else {
            DispatchQueue.main.async { () -> Void in
                activityIndicator.removeFromSuperview()
                strongSelf.imageView.image = strongSelf.flickrPhoto.largeImage
            }
        }
    }
}
于 2016-08-22T14:36:12.630 回答
29

在 XCode 8、Swift 3 中编译 https://github.com/rpthomas/Jedisware

 @IBAction func tap(_ sender: AnyObject) {

    let thisEmail = "emailaddress.com"
    let thisPassword = "myPassword" 

    DispatchQueue.global(qos: .background).async {

        // Validate user input

        let result = self.validate(thisEmail, password: thisPassword)

        // Go back to the main thread to update the UI
        DispatchQueue.main.async {
            if !result
            {
                self.displayFailureAlert()
            }

        }
    }

}
于 2016-10-04T23:30:08.487 回答
15

由于上面已经回答了 OP 问题,我只想添加一些速度注意事项:

在DispatchQueue.global中分配给异步函数的优先级类有很大的不同。

我不建议以.background线程优先级运行任务,尤其是在 iPhone X 上,任务似乎分配在低功耗内核上。

以下是计算密集型函数的一些真实数据,该函数从 XML 文件(带缓冲)读取并执行数据插值:

设备名称/.background/.utility/.default/.userInitiated/.userInteractive _ _ _ _ _ _ _

  1. iPhone X:18.7s / 6.3s / 1.8s / 1.8s / 1.8s
  2. iPhone 7:4.6s / 3.1s / 3.0s / 2.8s / 2.6s
  3. iPhone 5s:7.3s / 6.1s / 4.0s / 4.0s / 3.8s

请注意,并非所有设备的数据集都相同。它在 iPhone X 上是最大的,在 iPhone 5s 上是最小的。

于 2018-05-16T12:45:07.830 回答
6

我这样做了,如果你想刷新你的 UI 以显示新数据而不像 UITableView 或 UIPickerView 那样让用户注意到,这一点尤其重要。

    DispatchQueue.main.async
 {
   /*Write your thread code here*/
 }
于 2017-01-22T18:18:38.197 回答
6

Swift 5 的更新

串行队列

let serialQueue = DispatchQueue.init(label: "serialQueue")
serialQueue.async {
    // code to execute
}

并发队列

let concurrentQueue = DispatchQueue.init(label: "concurrentQueue", qos: .background, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)

concurrentQueue.async {
// code to execute
}

苹果文档

参数

标签

附加到队列的字符串标签,用于在调试工具(如 Instruments、sample、stackshots 和崩溃报告)中唯一标识它。因为应用程序、库和框架都可以创建自己的调度队列,所以建议使用反向 DNS 命名样式 (com.example.myqueue)。此参数是可选的,可以为 NULL。

服务质量

与队列关联的服务质量级别。该值确定系统调度任务执行的优先级。有关可能值的列表,请参阅 DispatchQoS.QoSClass。

属性

与队列关联的属性。包含 concurrent 属性以创建并发执行任务的调度队列。如果省略该属性,则调度队列会串行执行任务。

自动释放频率

自动释放由队列调度的块创建的对象的频率。有关可能值的列表,请参阅DispatchQueue.AutoreleaseFrequency

目标

在其上执行块的目标队列。如果您希望系统提供适合当前对象的队列,请指定 DISPATCH_TARGET_QUEUE_DEFAULT。

于 2019-08-01T04:47:09.890 回答
4
 DispatchQueue.main.async {
          self.collectionView?.reloadData() // Depends if you were populating a collection view or table view
    }


OperationQueue.main.addOperation {
    self.lblGenre.text = self.movGenre
}

//如果需要在视图控制器上填充对象(标签、图像视图、文本视图),请使用操作队列

于 2017-05-10T08:04:04.640 回答
2
   let concurrentQueue = dispatch_queue_create("com.swift3.imageQueue", DISPATCH_QUEUE_CONCURRENT) //Swift 2 version

   let concurrentQueue = DispatchQueue(label:"com.swift3.imageQueue", attributes: .concurrent) //Swift 3 version

我在 Xcode 8、Swift 3 中重新编写了您的代码,并且这些更改与您的 Swift 2 版本形成对比。

于 2017-02-27T08:15:05.583 回答
2
DispatchQueue.main.async(execute: {

// write code

})

串行队列:

let serial = DispatchQueue(label: "Queuename")

serial.sync { 

 //Code Here

}

并发队列:

 let concurrent = DispatchQueue(label: "Queuename", attributes: .concurrent)

concurrent.sync {

 //Code Here
}
于 2017-03-15T06:56:36.720 回答
2

斯威夫特 3

你想在 swift 代码中调用一些闭包然后你想在故事板中更改任何类型的更改都属于视图你的应用程序将崩溃

但是您想使用调度方法,您的应用程序不会崩溃

异步方法

DispatchQueue.main.async 
{
 //Write code here                                   

}

同步方法

DispatchQueue.main.sync 
{
     //Write code here                                  

}
于 2017-05-18T09:46:06.623 回答
1

对于斯威夫特 3

   DispatchQueue.main.async {
        // Write your code here
    }
于 2017-08-23T03:49:15.753 回答
1
 let newQueue = DispatchQueue(label: "newname")
 newQueue.sync { 

 // your code

 }
于 2017-10-12T07:37:21.207 回答
-3
DispatchQueue.main.async(execute: {
   // code
})
于 2017-05-15T04:28:14.687 回答
-4

现在很简单:

let serialQueue = DispatchQueue(label: "my serial queue")

默认是串行的,要获得并发,您可以使用可选的属性参数 .concurrent

于 2016-09-10T00:36:05.500 回答
-4

您可以在 swift 3.0 中使用此代码创建调度队列

DispatchQueue.main.async
 {
   /*Write your code here*/
 }

   /* or */

let delayTime = DispatchTime.now() + Double(Int64(0.5 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)                   
DispatchQueue.main.asyncAfter(deadline: delayTime)
{
  /*Write your code here*/
}
于 2017-01-06T06:40:30.677 回答