color bar ios swift

ios - bar - ¿Cómo utilizar hilo de fondo en swift?



uinavigationitem title color (14)

¿Cómo usar enhebrado en swift?

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


Versión Swift 3

Swift 3 utiliza la nueva clase DispatchQueue para administrar colas y subprocesos. Para ejecutar algo en el hilo de fondo usarías:

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

O si quieres algo en dos líneas de código:

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." } }

También puede obtener información detallada sobre GDC en Swift 3 en este tutorial .


Swift 3.0+

Mucho se ha modernized en Swift 3.0. Ejecutar algo en el hilo de fondo se ve así:

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 a 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 - Problema conocido

A partir de Swift 1.1, Apple no admitía la sintaxis anterior sin algunas modificaciones. Pasar QOS_CLASS_BACKGROUND realidad no funcionó, en lugar de eso use Int(QOS_CLASS_BACKGROUND.value) .

Para más información ver documentación de manzanas.


Debe separar los cambios que desea ejecutar en segundo plano de las actualizaciones que desea ejecutar en la interfaz de usuario:

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


Del tutorial de Jameson Quave.

Swift 2

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


En Swift 4.2 y Xcode 10

//To call function after some time DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { //Here call your function } //If you want to do changes in UI use this DispatchQueue.main.async(execute: { })


Grand Central Dispatch se utiliza para manejar la multitarea en nuestras aplicaciones de iOS.

Puedes usar este código

// Using time interval DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+1) { print("Hello World") } // Background thread queue.sync { for i in 0..<10 { print("Hello", i) } } // Main thread for i in 20..<30 { print("Hello", i) }

Más información, utilice este enlace: https://www.programminghub.us/2018/07/integrate-dispatcher-in-swift.html


La mejor práctica es definir una función reutilizable a la que se pueda acceder varias veces.

FUNCION REUTILIZABLE:

por ejemplo, en algún lugar como AppDelegate.swift como una función global.

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!(); } } } }

Nota: en Swift 2.0, reemplace QOS_CLASS_USER_INITIATED.value anterior con QOS_CLASS_USER_INITIATED.rawValue en su lugar

USO:

A. Para ejecutar un proceso en segundo plano con un retraso de 3 segundos:

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

B. Para ejecutar un proceso en segundo plano, ejecute una finalización en primer plano:

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. Para retrasar 3 segundos, observe el uso del parámetro de finalización sin el parámetro de fondo:

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


La respuesta de Dan Beaulieu en 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() }) } } } }

Uso

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 })


Realmente me gusta la respuesta de Dan Beaulieu, pero no funciona con Swift 2.2 y creo que podemos evitar esas desagradables revelaciones forzadas.

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() } } } }


Sin embargo, buenas respuestas, de todas formas quiero compartir mi solución Orientada a Objetos Actualizada para swift 3 .

por favor AsyncTask : AsyncTask

Inspirado conceptualmente en AsyncTask de Android, escribí mi propia clase en Swift

AsyncTask permite el uso correcto y fácil del hilo de la interfaz de usuario. Esta clase permite realizar operaciones en segundo plano y publicar resultados en el subproceso de la interfaz de usuario.

Aquí hay algunos ejemplos de uso

Ejemplo 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''

Ejemplo 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

Tiene 2 tipos genéricos:

  • BGParam : el tipo de parámetro enviado a la tarea en el momento de la ejecución.
  • BGResult : el tipo de resultado del cálculo de fondo.

    Cuando creas una AsyncTask, puedes usar esos tipos para lo que necesites para pasar dentro y fuera de la tarea en segundo plano, pero si no necesitas esos tipos, puedes marcarlos como no utilizados con solo configurarlos en: Void o con una sintaxis más corta : ()

Cuando se ejecuta una tarea asíncrona, pasa por 3 pasos:

  1. beforeTask:()->Void invocado en el hilo de la IU justo antes de que se ejecute la tarea.
  2. backgroundTask: (param:BGParam)->BGResult invocado en el hilo de fondo inmediatamente después
  3. afterTask:(param:BGResult)->Void invocado en el subproceso de la interfaz de usuario con el resultado de la tarea en segundo plano

Ya que la pregunta OP ya ha sido respondida anteriormente, solo quiero agregar algunas consideraciones de velocidad:

No recomiendo ejecutar tareas con la prioridad de subproceso .background especialmente en el iPhone X donde la tarea parece estar asignada en los núcleos de bajo consumo.

Aquí hay algunos datos reales de una función de computación intensiva que se lee de un archivo XML (con almacenamiento en búfer) y realiza la interpolación de datos:

Nombre del dispositivo / .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

Tenga en cuenta que el conjunto de datos no es el mismo para todos los dispositivos. Es el más grande en el iPhone X y el más pequeño en el iPhone 5s.


en Swift 4.2 esto funciona.

import Foundation class myThread: Thread { override func main() { while(true) { print("Running in the Thread"); Thread.sleep(forTimeInterval: 4); } } } let t = myThread(); t.start(); while(true) { print("Main Loop"); sleep(5); }


Swift 4.1

Pon esto en algún archivo:

func background(work: @escaping () -> ()) { DispatchQueue.global(qos: .userInitiated).async { work() } } func main(work: @escaping () -> ()) { DispatchQueue.main.async { work() } }

y luego llámalo donde necesites:

background { //background job main { //update UI (or what you need to do in main thread) } }


dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), { // Conversion into base64 string self.uploadImageString = uploadPhotoDataJPEG.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.EncodingEndLineWithCarriageReturn) })