Categories
Swift Development

GCD

Granth central dispatch (algo así como gran despacho central en español)

Si estas accediendo a datos remotos deberías usar un Hilo en segundo plano

Si estas ejecutando un código lento este también debería ir en el hilo de segundo plano

Si estas editando 100 fotos deben ir en multiples hilos en segundo plano

GCD nos ayuda a manejar multiples hilos GCD los crea en automático y los ejecuta en el modo mas eficiente que puede.

async()

async() es llamada dos veces primero cuando ponemos el código en un hilo en segundo plano y luego cuando lo regresamos al hilo principal

GCD funciona con un sistema de colas FIFO(First In, First Out)

GCD coloca tus tareas en esas colas dependiendo que tan importantes tu le indiques que son

Los bloques de código serán puestos en las colas en el orden que indiques pero como varios se ejecutan al mismo tiempo el orden de término no esta garantizado.

Que tan importante es cierto código depende de algo llamado calidad de servicio (“quality of service”, or QoS) que decide que nivel de servicio debe recibir el código.

En la cima esta the main queue que corre en el hilo principal, y debe ser usada para correr código que vaya actualizar la interfaz de usuario de inmediato incluso si esto bloquea el programa de hacer cualquier otra cosa. Hay otros 4 hilos que puedes usar cada una con su nivel de QoS

User Interactive el hilo en segundo plano mas importante, debe ser usado para trabajo que mantenga tu interfaz funcionado, la prioridad de este hilo pedirá al sistema que dedique todo el CPU disponible para tener el trabajo terminado lo más rápido posible.

User Initiated este debe ser usado para tareas solicitadas por el usuario que ahora este esperando para continuar usando la app (ejemplo el usuario presiona un botón), no tan importante como el anterior pero es muy importante por que mantiene al usuario en espera.

The Utility queue este debe ser usado para tareas largas de las cuales el usuario este consciente de ellas pero por las que no este necesariamente desesperado. Si el usuario requiere algo que puede feliz mente dejar corriendo mientras hace algo mas en tu app deberías correr utility.

The Background queue esta es para tareas largas que el usuario no esta activamente consciente de ellas o que no le interesa que se completen.

No es nunca bueno hacer trabajo de UI en el hilo secundario

Paul Hudson

Diferentes formas de mover el código a un hilo diferente

Usando DispatchQueue

main para la interfaz de usuario

DispatchQueue.main.async {
    self.tableView.reloadData()
}

global y userInitiated para peticiones del usuario por ejemplo el Json

DispatchQueue.global(qos: .userInitiated).async {
    if let url = URL(string: urlString) {
        if let data = try? Data(contentsOf: url) {
            self.parse(json: data)
            return
        }
    }

    self.showError()
}

Ahora recordemos que nunca es bueno modificar la UI en un hilo secundario por eso hay que mover lo que esta dentro de showError a el hilo principal

func showError() {
    DispatchQueue.main.async {
        let ac = UIAlertController(title: "Loading error", message: "There was a problem loading the feed; please check your connection and try again.", preferredStyle: .alert)
        ac.addAction(UIAlertAction(title: "OK", style: .default))
        self.present(ac, animated: true)
    }
}

Aunque esto es muy sencillo hay otra forma de usar GCD de forma muy sencilla

performSelector(inBackground: #selector(fetchJSON), with: nil)

Llamamos al metodo con performSelector

y la recarga de la tabla y alerta en otro método para regresar al hilo principal

performSelector(onMainThread: #selector(showError), with: nil, waitUntilDone: false)
func parse(json: Data) {
        let decoder = JSONDecoder()
        
        if let jsonPetitions = try? decoder.decode(Petitions.self, from : json){
            petitions = jsonPetitions.results
            
            
            tableView.performSelector(onMainThread: #selector(UITableView.reloadData), with: nil, waitUntilDone: false)
          
            
        }else{
            
            performSelector(onMainThread: #selector(showError), with: nil, waitUntilDone: false)
         
        }
    }

Referencias

https://www.hackingwithswift.com/read/9/overview

2 replies on “GCD”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *