Estoy siguiendo un tutorial sobre cómo trabajar con REST/web requests. En el tutorial, estamos trabajando hacia una aplicación Pokedex donde obtenemos detalles de Pokémon de una API usando Alamofire, y luego mostramos esos datos en nuestras IU.

Aquí está el código relacionado:

typealias DownloadComplete = (Bool) -> ()

// Model class
func downloadPokemonDetails(completed: @escaping DownloadComplete)
    {
        Alamofire.request(_pokemonURL).responseJSON { (response) in
            var success = true
            if let jsonData = response.result.value as? Dictionary<String, Any>
            {
                // parse the json here
                ...
            }
            else
            {
                success = false
            }
            completed(success)
        }
    }

// Controller class
override func viewDidLoad() {
        super.viewDidLoad()
        pokemon.downloadPokemonDetails(completed: { (success) in
            if success
            {
                self.updateUI()
            }
            else
            {
                print("FAILED: TO PARSE JSON DATA")
            }
        })
    }

func updateUI()
{
    attackLbl.text = pokemon.attack
    defenseLbl.text = pokemon.defense
    heightLbl.text = pokemon.height
    weightLbl.text = pokemon.weight
}

Ahora mi pregunta es: ¿no deberíamos usar DispatchQueue.main. y actualizar la interfaz de usuario allí como tal?

pokemon.downloadPokemonDetails(completed: { (success) in
            if success
            {
                DispatchQueue.main.async {
                    self.updateUI()
                }
            }

El tutorial lo dejó fuera y no estoy seguro de si se necesita DispatchQueue aquí para actualizar la interfaz de usuario. Sé que actualizar la interfaz de usuario en un hilo en segundo plano es una mala práctica, así que si alguien puede arrojar algo de luz sobre si usar DispatchQueue aquí para obtener el hilo principal es necesario o no, lo agradecería mucho.

3
aresz 14 dic. 2016 a las 08:55
2
¿Echaste un vistazo al Léame de Alamofire? - "Los controladores de respuesta de forma predeterminada se ejecutan en la cola de despacho principal. ...."
 – 
Martin R
14 dic. 2016 a las 09:01
Gracias por el comentario. En realidad, no lo he hecho, pero ¿eso significa que ya no necesito el DispatchQueue.main al actualizar la interfaz de usuario en este caso? Todavía soy nuevo en estas cosas.
 – 
aresz
14 dic. 2016 a las 09:03
1
Usted no necesita. Puedes comprobarlo antes del dispatch_get_current_queue() == dispatch_get_main_queue()
 – 
Neil Galiaskarov
14 dic. 2016 a las 09:10
Gracias @NeilGaliaskarov por confirmar. Me gustaría usar el fragmento que publicaste para verificar, pero dispatch_get_current_queue() ya está obsoleto y no puedo usarlo para averiguarlo por mí mismo. Parece que no puedo encontrar el reemplazo de eso.
 – 
aresz
14 dic. 2016 a las 09:16
5
if Thread.isMainThread { print("Main Thread") }
 – 
Neil Galiaskarov
14 dic. 2016 a las 09:21

1 respuesta

La mejor respuesta

Si uno no quiere leer toda la sección de comentarios, lo publico aquí como respuesta. En primer lugar, lea documentos de Alamofire, que dice claramente: "Los controladores de respuesta se ejecutan de forma predeterminada. en la cola de envío principal ".

Significa que puede llamar a cualquier código relacionado con la interfaz de usuario en el bloque de respuesta. Si aún no se siente cómodo confiando en un documento de biblioteca de terceros, puede verificarlo ejecutando este fragmento de swift3:

if Thread.isMainThread { 
   print("Main Thread") 
}

xcode 9

A partir de xcode 9 , hay un Main Thread Checker integrado que detecta el uso no válido de AppKit, UIKit y otras API desde un hilo en segundo plano. Main Thread Checker se habilita automáticamente cuando ejecuta su aplicación con el depurador de Xcode.

Si alguna parte de su proyecto contiene llamadas de IU no válidas desde un hilo en segundo plano, verá lo siguiente:

enter image description here

** Demostrado en Xcode versión 9.1 (9B55)

17
Neil Galiaskarov 22 feb. 2018 a las 07:44