如何在swift中使用后台线程?

如何在swift中使用线程?

dispatchOnMainThread:^{ NSLog(@"Block Executed On %s", dispatch_queue_get_label(dispatch_get_current_queue())); }]; 

Swift 3.0+

很多已经在Swift 3.0 现代化 。 在后台线程上运行一些东西看起来像这样:

 DispatchQueue.global(qos: .background).async { print("This is run on the background queue") DispatchQueue.main.async { print("This is run on the main queue, after the previous code in outer block") } } 

Swift 1.2到2.3

 let qualityOfServiceClass = QOS_CLASS_BACKGROUND let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0) dispatch_async(backgroundQueue, { print("This is run on the background queue") dispatch_async(dispatch_get_main_queue(), { () -> Void in print("This is run on the main queue, after the previous code in outer block") }) }) 

Pre Swift 1.2 – 已知问题

从Swift 1.1开始,Apple没有经过一些修改就不支持上面的语法。 传递QOS_CLASS_BACKGROUND实际上并不工作,而是使用Int(QOS_CLASS_BACKGROUND.value)

欲了解更多信息,请参阅苹果文档

最好的做法是定义一个可以多次访问的可重用函数。

可重复使用的function:

例如像AppDelegate.swift这样的全局函数。

 func backgroundThread(delay: Double = 0.0, background: (() -> Void)? = nil, completion: (() -> Void)? = nil) { dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)) { if(background != nil){ background!(); } let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))) dispatch_after(popTime, dispatch_get_main_queue()) { if(completion != nil){ completion!(); } } } } 

注意:在Swift 2.0中,用QOS_CLASS_USER_INITIATED.rawValuereplace上面的QOS_CLASS_USER_INITIATED.value

用法:

A.要在后台运行一个进程,延迟3秒:

  backgroundThread(3.0, background: { // Your background function here }) 

B.在后台运行一个进程然后在前台运行一个完成:

  backgroundThread(background: { // Your function here to run in the background }, completion: { // A function to run in the foreground when the background thread is complete }) 

C.延迟3秒钟 – logging使用完成参数,无背景参数:

  backgroundThread(3.0, completion: { // Your delayed function here to be run in the foreground }) 

Jameson Quave的教程

Swift 2

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { //All stuff here }) 

Dan Beaulieu在swift3的回答。

Swift 3.0.1

 extension DispatchQueue { static func background(delay: Double = 0.0, background: (()->Void)? = nil, completion: (() -> Void)? = nil) { DispatchQueue.global(qos: .background).async { background?() if let completion = completion { DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: { completion() }) } } } } 

用法

 DispatchQueue.background(delay: 3.0, background: { // do something in background }, completion: { // when background job finishes, wait 3 seconds and do something in main thread }) DispatchQueue.background(background: { // do something in background }, completion:{ // when background job finished, do something in main thread }) DispatchQueue.background(delay: 3.0, completion:{ // do something in main thread after 3 seconds }) 

Swift 3版本

Swift 3利用新的DispatchQueue类来pipe理队列和线程。 要在后台线程上运行一些东西,你可以使用:

 let backgroundQueue = DispatchQueue(label: "com.app.queue", qos: .background) backgroundQueue.async { print("Run on background thread") } 

或者如果你想要两行代码中的东西:

 DispatchQueue.global(qos: .background).async { print("Run on background thread") DispatchQueue.main.async { print("We finished that.") // only back on the main thread, may you access UI: label.text = "Done." } } 

在本教程中,您还可以在Swift 3中获得一些有关GDC的深入信息。

您必须从要在UI上运行的更新中分离出想要在后台运行的更改:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { // do your task dispatch_async(dispatch_get_main_queue()) { // update some UI } } 

好的答案虽然,无论如何,我想分享我的面向对象的解决scheme更新为迅速3

请查看: AsyncTask

从概念上来说,受到了Android的AsyncTask的启发,我在Swift中编写了自己的类

AsyncTask支持正确和简单地使用UI线程。 这个类允许执行后台操作并在UI线程上发布结果。

这里有几个用法示例

例1 –

 AsyncTask(backgroundTask: {(p:String)->Void in//set BGParam to String and BGResult to Void print(p);//print the value in background thread }).execute("Hello async");//execute with value 'Hello async' 

例2 –

 let task2=AsyncTask(beforeTask: { print("pre execution");//print 'pre execution' before backgroundTask },backgroundTask:{(p:Int)->String in//set BGParam to Int & BGResult to String if p>0{//check if execution value is bigger than zero return "positive"//pass String "poitive" to afterTask } return "negative";//otherwise pass String "negative" }, afterTask: {(p:String) in print(p);//print background task result }); task2.execute(1);//execute with value 1 

它有2个通用types:

  • BGParam – 执行时发送给任务的参数的types。
  • BGResult – 背景计算结果的types。

    当您创build一个AsyncTask时,您可以将这些types转换为任何需要传入和传出后台任务的types,但如果您不需要这些types,则可以将其设置为Void :将其设置为Void或语法较短:( ()

在执行asynchronous任务时,需要经过3个步骤:

  1. beforeTask:()->Void在执行任务之前在UI线程上调用beforeTask:()->Void
  2. backgroundTask: (param:BGParam)->BGResult在后台线程后立即调用backgroundTask: (param:BGParam)->BGResult
  3. afterTask:(param:BGResult)->Void在UI线程上使用后台任务的结果调用的afterTask:(param:BGResult)->Void

我真的很喜欢Dan Beaulieu的回答,但是它不适用于Swift 2.2,我想我们可以避免那些令人讨厌的强制解开!

 func backgroundThread(delay: Double = 0.0, background: (() -> Void)? = nil, completion: (() -> Void)? = nil) { dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { background?() if let completion = completion{ let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))) dispatch_after(popTime, dispatch_get_main_queue()) { completion() } } } } 
 dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), { // Conversion into base64 string self.uploadImageString = uploadPhotoDataJPEG.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.EncodingEndLineWithCarriageReturn) })